avr-gcc bug with floats?

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi everybody,
i've been using avr-gcc for a while, so first.. thanks to all of you for making this wonderful port!

now I have a problem.. i want the code below to be executed. messageBuf[1] contains a byte received through a I2C bus.

----------------------------
unsigned short t;
t = messageBuf[1]*((OCR1A_MAX-OCR1A_MIN)/256.0);
t += OCR1A_MIN ;
OCR1A = t;
-----------------

Take a look at the "256.0" ... if I replace it for "256" everything works fine, but i want to use more precision (even if it's then converted to unsigned shrot again).

ex: let messageBuf[1] be 1,
and
#define OCR1A_MAX 3000
#define OCR1A_MIN 2

messageBuf is defined as unsigned char messageBuf[4]

unsigned short t;
t = messageBuf[1]*((OCR1A_MAX-OCR1A_MIN)/256.0);
t += OCR1A_MIN ;
OCR1A = t;

When i use just "256" it works fine and I get 13.
but then i try with "256.0" just like the code below and OCR1A is now 65424 (or something like that, really hughe)

am I missing something out?? which is the correct way to do it then?

thanks in advance
oh.. it's an atmega8

and.. btw.. if i do

unsigned short t;
messageBuf[1] = 0x01;
t = messageBuf[1]*((OCR1A_MAX-OCR1A_MIN)/256.0);
t += OCR1A_MIN ;
OCR1A = t;

OCR1A equals to 65527.. weird huh?

i believe as if I am doing a stupid thing here but can't finally figure it out..

C

UPDATE> oh yes.. I used proteus to simulate the AVR, maybe proteus isis is wrong??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't think there is a float bug int gcc, I think there is a difference between your original code and what you posted:

65527u = 0xFFF7 = -9i

which is exactly what you would get if you calculated:

t = messageBuf[1]*((OCR1A_MIN-OCR1A_MAX)/256.0);
t += OCR1A_MIN ; 

note that min and max are swapped! I would start from there and go backwards.

Happy hacking
Markus

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try using a cast in the line:

t = (short)(messageBuf[1]*((OCR1A_MAX-OCR1A_MIN)/256.0)); 

When you use the 256.0 the entire expression is converted to floating point, and I think the compiler simply "truncates" the exceeding bytes when assigning this float to your short. That's why you get a 16-value that doesn't represent the value you want.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks for the replies..

it's not the order of OCR1A_MAX and MIN. The code I posted is just Control+C Control+V

About the truncating thing... I tried it, but.. still the same.

but... i just tried to simulate it with AVRstudio and found out that it's working just fine!!

so.. after all.. it seems to be a Proteus bug :S

quite awful and strange

thank you guys