CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Double Precision Float

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ljbeng



Joined: 10 Feb 2004
Posts: 205

View user's profile Send private message

Double Precision Float
PostPosted: Thu Jul 19, 2007 10:24 am     Reply with quote

I don't need any DOUBLE precision float for any math functions in the PIC chip. I only need it to program the base of a GPS receiver.

If I have a (4 byte) floating point number such as 40.345333, I need to convert that to an 8 byte double precision, only to send to the serial port of the GPS receiver. Is there a method to do this? I need to experiment with trying this, it may not work if the base does not like the precison of converting a single to double.

I have 3.249 and a PIC18F2620.
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Thu Jul 19, 2007 11:15 am     Reply with quote

Is the GPS looking for binary bytes or ascii digits? I would approach this as a string manipulation problem.
_________________
The search for better is endless. Instead simply find very good and get the job done.
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Thu Jul 19, 2007 12:08 pm     Reply with quote

Quote:
f I have a (4 byte) floating point number such as 40.345333

This has 8 significant decimal digits and will never be expressed without approximation in a 23 bit mantissa. Remember numbers exist on their own in this universe and what we take to be a number is merely a notational representation of its existence. For Navigation the notation is deg,mins and seconds or possibly in your case seconds extended to 2 decimal places or maybe degs.nnnnnn. You then further encode this in a floating point representation of your deg,min,sec notation. This may often cause a notational loss of accuracy and this may well be why you seek to an 8 byte floating pt representation. It is far easier to avoid errors from notation within notation issues by either using a string to notate the value
"40345333" 8 bytes with an implied decimal point or keep degs mins and seconds in integer fields. Ex deg int8, mins int8 and seconds int16 with an implied decimal pt ( 4 bytes total). The loss of information you are seeing is a result of binary versus decimal notation and a finite bit space for the exponent and the mantissa. The value 1/3 cannot be expressed accurately in binary notation or even decimal notation yet the string "1/3" captures its value accurately. This often called rounding but strictly speaking rounding is a choice to leave details out but this rounding is unavoidable short of changing the notational base to 3 to express 1/3 as 0.1 base 3
ljbeng



Joined: 10 Feb 2004
Posts: 205

View user's profile Send private message

PostPosted: Thu Jul 19, 2007 1:41 pm     Reply with quote

I am not looking for accuracy.

The instructions of the GPS receiver say it must receive a Double Precision, 8 byte representation of the latitude 40.123456. The accuracy of the latitude is +-30ft so the value does not need to be 16 decimal points accurate. I just need to convert the number from a 4 byte floating to an 8 byte floating.
Ttelmah
Guest







PostPosted: Thu Jul 19, 2007 3:08 pm     Reply with quote

You will need to do a little more, since I'd expect the device to want IEEE floats, rather than PIC floats.
Basically, you will have to extract the 23bit mantissa, sign bit, and 8 bit exponent from the PIC format, then on the exponent, add 896 (the 8 bit format uses a 1023 offset value, while the 11 bit format uses 127), and put the bits into the required locations in the 8 byte result...
It is not too complex to do, since (fortunately), except for adjusting the exponent, and re-arranging the data, you can just extend the mantissa with 0's.
It depends a lot on whether you want a really fast and neat way of doing this, or are prepared to accept simpler code, at a cost in performance?.
Now, no warranties on this, probably have the bit orders all wrong... :
Code:

struct data {
   int8 b[8]
};

union access {
   int8 b[4];
   float fp;
};

struct data convert_to_eight(union access val) {
   int16 temp;
   int1 sign;
   int8 ctr;
   stuct data result;
   temp=make16(0,val.b[0]);
   temp+=896;
   //temp is now the 11bit exponent required
   temp<<=4;
   //move left 4 bits.
   sign=bit_test(val.fp,8); //sign bit
   val.b[0]=0;
   bt_clear(val.fp,8);
   //shift the bytes left 5 bits
   for (ctr=0;ctr<5;ctr++) shift_left(&val.fp,4,0);
   //fill with zeros
   for (ctr=0;ctr<8;ctr--) result.b[ctr]=0;
   //now transfer the 23bit mantissa
   for (ctr=0;ctr<4;ctr++) result.b[ctr+1]=val.b[ctr];
   //put in the sign bit
   if (sign) bit_set(result.b[0],7);
   //Now need to move in the exponent, without damaging what is there
   result.b[0]|=make8(temp,1); //I think this is the right byte...
   result.b[1]|=make8(temp,0);
   return(result);
}

This will almost certainly be well wrong. You will need to test with a known 32bit FP value, against some know required outputs. However the basic 'idea' is sound. You have to extract the 8bit exponent into a 16bit value, and add 896. Then because this is offset by four bits in the output, shift this to the required spot. Then you have to move the mantissa left (filling both sides with zeros), and put the whole thing back together...
The result, will be an eight byte aray containing the bytes, and the function is called with the PIC FP value.


Best Wishes
ljbeng



Joined: 10 Feb 2004
Posts: 205

View user's profile Send private message

PostPosted: Thu Jul 19, 2007 3:55 pm     Reply with quote

Thanks, I will start there.

Yes I can compare known good DP floats and the SP float.

Thanks.
Ken Johnson



Joined: 23 Mar 2006
Posts: 197
Location: Lewisburg, WV

View user's profile Send private message

PostPosted: Thu Jul 19, 2007 5:49 pm     Reply with quote

Look at ieeefloat.c in the drivers folder. Only does 32-bit, but that's a start. Shouldn't be too difficult to extend to 64-bit, maybe Smile

Ken
ljbeng



Joined: 10 Feb 2004
Posts: 205

View user's profile Send private message

PostPosted: Fri Jul 27, 2007 7:26 am     Reply with quote

Good Old Wikepedia explained single and double very nicely.

This only converts a 4 byte single floating to an 8 byte double floating but does not increase the accuracy of the number. This just merely rearranges the bits to match the double bit pattern.


Code:
void cvd(int32 vl) {

int sign;
int32 exp;
int32 b1,b2,b3;

sign = bit_test(vl,31);

exp = (int32)vl >> 23;
exp &= 0xff;
exp += 896;

b1 = vl & 0x7fffff;
b1 = b1 << 9;

b2 = exp << 20;
if (sign) bit_set(b2,31);
b2 += b1>>12;//ms 4 bytes
b3 = b1 << 20;//ls 4 bytes

}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group