Go Down

### Topic: Combining bitwise and integer math (Read 1 time)previous topic - next topic

#### Stafford

##### May 26, 2009, 07:41 pmLast Edit: May 26, 2009, 07:43 pm by staffordj Reason: 1
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:
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*=10000;
Any idea why the original method didn't work out?

#1
##### May 26, 2009, 08:35 pm
It's very likely a problem with "type promotion".  How are Whole and TReading declared?

- Brian

#### Stafford

#2
##### May 26, 2009, 08:44 pm
I tried both int and long.  I also tried to typecast to int, but I am not sure my syntax is correct:

#### AWOL

#3
##### May 26, 2009, 08:47 pm
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
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

#### AWOL

#4
##### May 26, 2009, 08:53 pm
Code: [Select]
`(int) (TReading >>4) * 10000L;`
Maybe?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

#### Stafford

#5
##### May 26, 2009, 09:05 pm
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?

#6
##### May 26, 2009, 10:05 pm
If there is then the compiler has a serious bug.  In other words, this is very unlikely to be the problem.

- Brian

#### Stafford

#7
##### May 28, 2009, 05:11 amLast Edit: May 28, 2009, 05:12 am by staffordj Reason: 1
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.

Go Up