user61096: I am using an infrared sensor called OTI301. In its data sheet it says that in order to obtain object temperature and ambient temperature values I need to extract the binary information from the sensor and use the binary information in given formulas. I have done all that but for some reason I am not getting the right values for the object temperature. The ambient temperature seems to work well but when I put a hot object, more than 320 F, the formula returns a random negative number. Also the the sensor can go up to 780 F so I know the temperature has not been capped. Please see pictures for important data sheet information, or here are the links for the complete data sheets
https://drive.google.com/file/d/1XMRDCNzY3fn0q6lkGejs5D-pqksfRuZ8/view?usp=sharing.
https://drive.google.com/file/d/1mmdkHkNbwC5VgQxGMrq07XolajNvgBkN/view?usp=sharing. Lastly, here is the part of the code where I extract the information and apply formulas.
     void loop() 
 {
   if (Wire.read()) // On success, read() will return 1, on fail 0.
   {
     buttonState = digitalRead(button);
     //Serial.println(buttonState);
     Wire.beginTransmission(DEVICE_ADDRESS);
     Wire.write(0x80);  // readout command 
     Wire.endTransmission(false); 
     Wire.requestFrom(DEVICE_ADDRESS, 6); // request 6 bytes
     uint8_t data[6];
     for (int i = 0; i < 6; i++) {
         data[i] = Wire.read();
     }

      //Calculate Object Temperature
     if(data[5] < 0x80) {
       TA = (data[3]+ data[4]*256+data[5]*65536)/200;  
     }
     else {
       TA = (((data[3]+ data[4]*256+data[5]*65536)) - 16777216) /200;  
     }

     //Calculate Ambient Temperature
     if(data[2] < 0x80) {
       TA = (data[0]+ data[1]*256+data[2]*65536)/200;
      }
     else {
       TA = (((data[0]+ data[1]*256+data[2]*65536)) - 16777216) /200;
     }



user2967: You said "I defined TA as a float." That doesn't matter. In C/C++, expressions are only "promoted" to a larger/different data type AFTER they are evaluated. Your calculations are being done using 16-bit ints, which overflow, and then cast to a float. 
(C/C++ evaluates expressions from the inner-most outward, and if one of the operands to an operator is a larger type, it will "promote" the other operand to the larger type before doing a calculation. It won't notice that a calculation will overflow and promote the operands to fix that problem however.)
Try this:
   TA = (data[3]+ data[4]*256+uint64(data[5])*65536)/200;  

That version of the code forces data[5] to an unsigned long before multiplying it by 65536.
Do the same thing to the value that you multiply by 65536 in all of your expressions and you should avoid overflow.

user7508: The rules of integer arithmetics are tricky in C++. There are rules that
give the type of integer literals:

256 and 200 are of type int, which is the default type for
integer literals. On the Nano, this type is 16-bits, and covers the
range from −32,768 to +32,767.
65536 being too large for the int type, it is implicitly
considered a long int. This type is 32-bits on the Nano, and covers
roughly ±2.15×109.

Then there are rules for the types used in arithmetic operations. No
computation is ever done on a type smaller than int: anything smaller
is promoted to int. Then, if you combine two operands of different
types, the larger type “wins” and the compiler implicitly converts the
other operand to the larger type. Note that if two types have the same
bit size, the unsigned one is considered “larger”.
Let's go now through your formula, and see the types of the different
terms:
data[3]       = uint8_t
data[4]*256   = uint8_t * int → int
data[5]*65536 = uint8_t * (long int) → long int

Now you may see the problem. Your calculation will eventually overflow,
but the overflow is not in data[5]*65536, as one may naively expect.
What happens is than when the temperature reaches 163.84 °C (≈ 327 °F),
data[4] becomes 128, and data[4]*256 is 32,768, just too large for
an int. The result overflows to −128, hence the negative values you
see.
The simplest solution is to force 256 to be a long int, by appending
the L suffix to the number. Then the multiplication will be performed
with the long int type, and there will be no overflow:
TA = (data[3] + data[4]*256L + data[5]*65536) / 200;


On a final note, it is worth noting that the numbers 256, 65536 and
16777216 used in the formula are all powers of two. Even powers of 256.
You may notice that, save for the division by 200, what this formula
describes is the coding of an integer as a 24-bit, little-endian, two's
complement number. This format (two's complement little-endian) is
exactly what the Arduino uses internally for representing numbers. You
could then avoid all those calculations and get your result by just
telling the compiler that what those memory cells are actually holding
is a 24-bit integer:
float TA = *(__int24*)&data[3] / 200.0;

This works for both positive and negative temperatures, but it has the
drawback of breaking some C++ rules (aliasing rules), and using the
non-standard type __int24. A safest way to achieve the same is to
build a 32-bit integer by putting the bits in place using bitwise
operations. But note that then a sign-extension byte is needed to
convert the 24-bit number to 32 bits:
uint8_t sign_extension = data[5] & 0x80 ? 0xff : 0x00;
int32_t reading = (uint32_t) data[3] <<  0
                | (uint32_t) data[4] <<  8
                | (uint32_t) data[5] << 16
                | (uint32_t) sign_extension << 24;
float TA = reading / 200.0;


61096: <p>I am using an infrared sensor called OTI301. In its data sheet it says that in order to obtain object temperature and ambient temperature values I need to extract the binary information from the sensor and use the binary information in given formulas. I have done all that but for some reason I am not getting the right values for the object temperature. The ambient temperature seems to work well but when I put a hot object, more than 320 F, the formula returns a random negative number. Also the the sensor can go up to 780 F so I know the temperature has not been capped. Please see pictures for important data sheet information, or here are the links for the complete data sheets
<a href="https://drive.google.com/file/d/1XMRDCNzY3fn0q6lkGejs5D-pqksfRuZ8/view?usp=sharing" rel="nofollow noreferrer">https://drive.google.com/file/d/1XMRDCNzY3fn0q6lkGejs5D-pqksfRuZ8/view?usp=sharing</a>.
<a href="https://drive.google.com/file/d/1mmdkHkNbwC5VgQxGMrq07XolajNvgBkN/view?usp=sharing" rel="nofollow noreferrer">https://drive.google.com/file/d/1mmdkHkNbwC5VgQxGMrq07XolajNvgBkN/view?usp=sharing</a>. Lastly, here is the part of the code where I extract the information and apply formulas.</p>

<pre><code>     void loop() 
 {
   if (Wire.read()) // On success, read() will return 1, on fail 0.
   {
     buttonState = digitalRead(button);
     //Serial.println(buttonState);
     Wire.beginTransmission(DEVICE_ADDRESS);
     Wire.write(0x80);  // readout command 
     Wire.endTransmission(false); 
     Wire.requestFrom(DEVICE_ADDRESS, 6); // request 6 bytes
     uint8_t data[6];
     for (int i = 0; i &lt; 6; i++) {
         data[i] = Wire.read();
     }

      //Calculate Object Temperature
     if(data[5] &lt; 0x80) {
       TA = (data[3]+ data[4]*256+data[5]*65536)/200;  
     }
     else {
       TA = (((data[3]+ data[4]*256+data[5]*65536)) - 16777216) /200;  
     }

     //Calculate Ambient Temperature
     if(data[2] &lt; 0x80) {
       TA = (data[0]+ data[1]*256+data[2]*65536)/200;
      }
     else {
       TA = (((data[0]+ data[1]*256+data[2]*65536)) - 16777216) /200;
     }
</code></pre>

<p><a href="https://i.stack.imgur.com/OITof.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/OITof.png" alt="enter image description here"></a></p>
 2967: <p>You said "I defined TA as a float." That doesn't matter. In C/C++, expressions are only "promoted" to a larger/different data type AFTER they are evaluated. Your calculations are being done using 16-bit ints, which overflow, and <strong>then</strong> cast to a float. </p>

<p>(C/C++ evaluates expressions from the inner-most outward, and if one of the operands to an operator is a larger type, it will "promote" the other operand to the larger type before doing a calculation. It <strong>won't</strong> notice that a calculation will overflow and promote the operands to fix that problem however.)</p>

<p>Try this:</p>

<pre><code>   TA = (data[3]+ data[4]*256+uint64(data[5])*65536)/200;  
</code></pre>

<p>That version of the code forces data[5] to an unsigned long <strong>before</strong> multiplying it by 65536.</p>

<p>Do the same thing to the value that you multiply by 65536 in all of your expressions and you should avoid overflow.</p>
 7508: <p>The rules of integer arithmetics are tricky in C++. There are rules that
give the type of integer literals:</p>

<ul>
<li><p><code>256</code> and <code>200</code> are of type <code>int</code>, which is the default type for
integer literals. On the Nano, this type is 16-bits, and covers the
range from −32,768 to +32,767.</p></li>
<li><p><code>65536</code> being too large for the <code>int</code> type, it is implicitly
considered a <code>long int</code>. This type is 32-bits on the Nano, and covers
roughly ±2.15×10<sup>9</sup>.</p></li>
</ul>

<p>Then there are rules for the types used in arithmetic operations. No
computation is ever done on a type smaller than <code>int</code>: anything smaller
is promoted to <code>int</code>. Then, if you combine two operands of different
types, the larger type “wins” and the compiler implicitly converts the
other operand to the larger type. Note that if two types have the same
bit size, the unsigned one is considered “larger”.</p>

<p>Let's go now through your formula, and see the types of the different
terms:</p>

<pre><code>data[3]       = uint8_t
data[4]*256   = uint8_t * int → int
data[5]*65536 = uint8_t * (long int) → long int
</code></pre>

<p>Now you may see the problem. Your calculation will eventually overflow,
but the overflow is <em>not</em> in <code>data[5]*65536</code>, as one may naively expect.
What happens is than when the temperature reaches 163.84 °C (≈ 327 °F),
<code>data[4]</code> becomes 128, and <code>data[4]*256</code> is 32,768, just too large for
an <code>int</code>. The result overflows to −128, hence the negative values you
see.</p>

<p>The simplest solution is to force 256 to be a <code>long int</code>, by appending
the <code>L</code> suffix to the number. Then the multiplication will be performed
with the <code>long int</code> type, and there will be no overflow:</p>

<pre class="lang-cpp prettyprint-override"><code>TA = (data[3] + data[4]*256L + data[5]*65536) / 200;
</code></pre>

<hr>

<p>On a final note, it is worth noting that the numbers 256, 65536 and
16777216 used in the formula are all powers of two. Even powers of 256.
You may notice that, save for the division by 200, what this formula
describes is the coding of an integer as a 24-bit, little-endian, <a href="https://en.wikipedia.org/wiki/Two%27s_complement" rel="nofollow noreferrer">two's
complement</a> number. This format (two's complement little-endian) is
exactly what the Arduino uses internally for representing numbers. You
could then avoid all those calculations and get your result by just
telling the compiler that what those memory cells are actually holding
is a 24-bit integer:</p>

<pre class="lang-cpp prettyprint-override"><code>float TA = *(__int24*)&amp;data[3] / 200.0;
</code></pre>

<p>This works for both positive and negative temperatures, but it has the
drawback of breaking some C++ rules (aliasing rules), and using the
non-standard type <code>__int24</code>. A safest way to achieve the same is to
build a 32-bit integer by putting the bits in place using bitwise
operations. But note that then a sign-extension byte is needed to
convert the 24-bit number to 32 bits:</p>

<pre class="lang-cpp prettyprint-override"><code>uint8_t sign_extension = data[5] &amp; 0x80 ? 0xff : 0x00;
int32_t reading = (uint32_t) data[3] &lt;&lt;  0
                | (uint32_t) data[4] &lt;&lt;  8
                | (uint32_t) data[5] &lt;&lt; 16
                | (uint32_t) sign_extension &lt;&lt; 24;
float TA = reading / 200.0;
</code></pre>
