View previous topic :: View next topic |
Author |
Message |
kmp84
Joined: 02 Feb 2010 Posts: 346
|
Float variable |
Posted: Tue Oct 11, 2011 4:07 am |
|
|
I have this bytes [8F 80 48 40] which represent "197182.000000" floating point number in "Modbus Poll" tool. BUT When I use make32 () Code: |
MFR=MAKE32(Buffer[3],Buffer[4],Buffer[5],Buffer[6]);
lcd_putc("\fMFR:");
printf(lcd_putc,"%f",MFR); |
I see: "2367324.30".
My compiler ver.4.104 ,PIC18F2525. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
Re: Float variable |
Posted: Tue Oct 11, 2011 4:40 am |
|
|
kmp84 wrote: | I have this bytes [8F 80 48 40] which represent "197182.000000" floating point number in "Modbus Poll" tool. BUT When I use make32 () Code: |
MFR=MAKE32(Buffer[3],Buffer[4],Buffer[5],Buffer[6]);
lcd_putc("\fMFR:");
printf(lcd_putc,"%f",MFR); |
I see: "2367324.30".
My compiler ver.4.104 ,PIC18F2525. |
Yes, that is odd. There shouldn't be any fractional part of the result.
...
That's not what you are expecting however. You are getting very confused about floating point numbers and integers. The bytes you give, 8F 80 48 40, appear to be the big-endian ordering of the IEEE-754 32 bit floating point representation of 197182.0. CCS's numerical convertor gives the 32 bit hex as 0x48408F80. So, for a start you have a byte ordering issue to sort out. Next you have to consider that CCS C uses the Microchip floating point format, which is NOT IEEE-754 compatible. The Microchip float32 hex equivalent for 197182.0 is 0x808F4090, which is -1.3155637E-38 in IEEE format. So you have a pretty big number format conversion issue to deal with. You perhaps can see some connection between the two, but its not straightforward.
Then you use an integer routine to put the bytes back into 32 bits. The result of that should be either 1212190592 or -1887418304 depending on endianness. This integer should then, assuming you've declared MFR as a float, be converted to the nearest float representation of that number, which shouldn't have any decimal places, but may well have due to loss of precision.
The biggest problem you have is that you need to convert IEEE-754 format float to Microchip float format. That's not easy. Instead learn a basic rule: don't send floats across networks/comms links. Use ASCII, use scaled integers, use anything other than floating point.
RF Developer |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Tue Oct 11, 2011 6:54 am |
|
|
Though I agree wholeheartedly with avoiding sending floats in a format like this, if you must, look at ieeefloat.c in the CCS drivers directory, which contains the routines to convert to/from ieee format.....
Best Wishes |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 346
|
|
Posted: Tue Oct 11, 2011 7:27 am |
|
|
I saw your post Ttelmah and try this(using ieeefloat.c) ,but result didn't true.
True value is :"[8F 80 48 40] ---->"197182.000000""(float).
Thanks. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Tue Oct 11, 2011 8:30 am |
|
|
You have a second problem.
Your pairs of bytes are being swapped.
The PIC is receiving 48408F80
You first and second byte pairs are swapped. You need to fix this in your make32, and then convert the value with f_IEEEtoPIC.
Best Wishes |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 346
|
|
Posted: Wed Oct 12, 2011 3:35 am |
|
|
It's work. Thank you very much! This is the MODBUS floating point data if any other have a same problem. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
|
|