View previous topic :: View next topic |
Author |
Message |
Tom-H-PIC
Joined: 08 Sep 2003 Posts: 105 Location: New Castle, DE
|
Float and bytes? |
Posted: Thu May 24, 2012 6:10 pm |
|
|
Hello All
How can I get to the bytes of a float.
I want to load the second byte with the fraction part of a number.
I have tried this but no fractional part when I load f0 with the data.
And then print bnr_float.ftotal out.
Code: |
union {
struct{
unsigned int f2;
unsigned int f1;
unsigned int f0;
unsigned int eb;
} fstuf;
float ftotal;
} bnr_float;
|
Thanks
Tom |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 24, 2012 6:50 pm |
|
|
Do you really want the byte ? Or do you want the fractional portion
of the float ? If so, use the modf() function to split the float into
the integer and fractional parts. |
|
|
Tom-H-PIC
Joined: 08 Sep 2003 Posts: 105 Location: New Castle, DE
|
|
Posted: Thu May 24, 2012 7:15 pm |
|
|
Well I'm working with ARINC 429 BNR data so it has all kind of bit field length and resolutions.
But as long as the range scale is grater then 1 I think can just stuff the fraction bits in to the float byte f0,f1.
That would be faster and more efficient I think.
Thanks for the reply
Tom |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri May 25, 2012 12:07 am |
|
|
I assume, you are talking about MCHP float format used with 8 bit PICs in contrast to IEEE single precision used with PIC24?
Are you sure to understand the format correctly? It's shown in the June 2011 CCS C reference manual on page 336
"What is the format of floating point numbers?". |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Fri May 25, 2012 1:50 am |
|
|
Tom-H-PIC wrote: | Well I'm working with ARINC 429 BNR data so it has all kind of bit field length and resolutions.
But as long as the range scale is grater then 1 I think can just stuff the fraction bits in to the float byte f0,f1.
That would be faster and more efficient I think.
Thanks for the reply
Tom |
I think you seriously misunderstand 'float'....
In microprocessors like this, the 'float' stored is entirely fractional!. It is a binary value, working as a 24bit binary mantissa, scaled as 1.xxxxxxxx with only the 23 'fractional' bits actually stored!. Then there is a single byte exponent, which gives the scale of this value.
So the bits being stored are only the binary fractional part, with a leading 'non fractional' 1, being implied, but not stored. This binary value is then scaled by the exponent. Effectively an extra 'bit' of data is being implied, without using any storage.
The only numeric value that can't be stored this way, is '0' (since it can't be scaled to have a leading '1'). This is handled by having the special case of all zeros stored, being used to imply '0'.
To directly write the value, you'd need first of all to scale your entire value (decimals, and fractional part) by repeated multiplications or divisions by 2, till in binary, it is in '1.xxxxxxx' format. Then write the xxxxxxx, together with the sign bit (for +ve or -ve number), into the last three bytes of the float. Then the record of how many divisions or multiplications it took to get to be this size, into the single first byte (treat as a signed value, with each division increasing the value by one, and each multiplication decreasing it by one).
Best Wishes |
|
|
Tom-H-PIC
Joined: 08 Sep 2003 Posts: 105 Location: New Castle, DE
|
|
Posted: Fri May 25, 2012 6:40 am |
|
|
Thank you all for the replies.
No I guess I did not totally understand float storage.
Yes FvM I did know about that information in the CCS reference manual and I also found the Microchip AN575.
So I thought I understood how it worked I guess not though.
But with Ttelmah explanation and reviewing the AN575 I do see how it works now.
I have a function for using bit weighting and bit shifting but it is really tedious and not efficient at all.
But it works.
I was just look for an elegant fast and efficient way to convert the data.
Again thanks for all the information and pointing out the errors of my ways.
Cheers |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Fri May 25, 2012 7:14 am |
|
|
As a comment, ARINC 429 BNR, is normally scaled according to the device sending it. So (for instance) you might have a compass device, returning a purely binary fractional number, from -1 to 1, corresponding to angles round a circle, and it's definition says that these are in effectively 1/180th degree steps.
All you need do, is write the value into a signed int32 directly from the 32bit field in the data, and then multiply the result by 0.00555555, to give a float with the values required from this device. The scaling needed is dependant on the device, but a single multiplication is all that is ever needed to decode this data.
Perhaps this might be a lot easier and quicker than the approach you currently have.
Best Wishes |
|
|
Tom-H-PIC
Joined: 08 Sep 2003 Posts: 105 Location: New Castle, DE
|
|
Posted: Fri May 25, 2012 11:34 am |
|
|
Ok Ttelmah
This is of interest.
I total understand about the scaling of the labels.
But the labels I'm going to be working with on this project are all speed, distance and temp at this time. Not working with anything like HDG, lat, long and or deviation.
From a tech side I have work with 429 for years but not from a software / hardware engineering side.
With this idea I have work out an elegant and efficient way of converting the data to float.
From the specification I know the total number of bits of data plus the sign.
I also know the number of fractional bits from the resolution.
So what I do is by shifting the data right or left as need to get the integer part of the data in the MSB 16 bits of a sign int32 and the fractional part in the lower 16 bits then divide by 65536.
Is seems to be working out good still testing.
Notwithstand Thanks A Lot Ttelmah!
Cheers
Tom |
|
|
|