Combining bitwise and integer math

I am working on a temperature control application using DS18B20 temp sensor. I wrote code to convert the serial data into a temperature. In order to troubleshoot I set it up in MS Visual C++ with some test values. I used the following statement to get the whole portion of the temp and scale it so I can add the fraction portion and return it as an integer:
Whole= (TReading >> 4) 10000;
It worked fine in visual c++, but did not work in Arduino. After trying a few things (OK, more than a few) I found that this works:
Whole= (TReading >> 4) ;
Whole
=10000;
Any idea why the original method didn't work out?

It's very likely a problem with "type promotion". How are Whole and TReading declared?

  • Brian

I tried both int and long. I also tried to typecast to int, but I am not sure my syntax is correct:
(int) (TReading >>4) * 10000;

As Coding Badly said, if you declared your variables as "int" in VC++, they won't be the same size "int" in Arduino.

It's one of the quirks of C (and by extension, C++) that "int" is was originally meant to be the native word size of the processor.

On an Arduino, sizeof (int) returns "2", whereas on a Pentium derivative, it will return "4".

Automatic type promotion is another tricky legacy of 'C'

http://home.att.net/~jackklein/c/inttypes.html

(int) (TReading >>4) * 10000L;

Maybe?

Thinking about it a little more, I am not certain I up'd TReading to long because it was holding a 2 byte integer. I am sure I had Whole set to long. Is there a temporary int generated to hold the intermediate value that is overflowing?

If there is then the compiler has a serious bug. In other words, this is very unlikely to be the problem.

  • Brian

Whole = (TReading >> 4) * 10000L did the trick. C and C++ are supposed to follow the same rules for promotion and default to the largest size involved. In this case, I guess it was evaluating the expression ((TReading >>4 ) *10000) as int since both TReading and 10000 were int and then promoting to long for the assignment to Whole. Using 10000L forces the promotion to happen before the expression is evaluated and prevents the overflow. Thanks for the help.