|
|
View previous topic :: View next topic |
Author |
Message |
XorpiZ Guest
|
array of float problems |
Posted: Wed Nov 30, 2005 9:19 am |
|
|
Hi.
I've defined an array like this
Code: | float predefined_coordinates[27][2] = {5454.1433,948.6149}; |
(Theres 26 others just like it, but that's not the point here)
After I defined the array, i do a;
Code: | printf("%f\n\r", predefined_coordinates[0][0]); |
And now, to the problem. The output is;
Why is that?[/code] |
|
|
Ttelmah Guest
|
|
Posted: Wed Nov 30, 2005 9:44 am |
|
|
Because floating point numbers are not accurate.
They only comprise 24bits of data for the number 'part', giving a basic accuracy of about six and a half digits. The error, may be up to the value 1 part in 'FLT_EPSILON' (defined in float.h).
This is inherent in _all_systems using FP maths, it is just that on the PC, the commonest form used, is the 'double', using twice as many bytes to store the value.
There have been lots of posts about this in the past, as well as suggestions for ways to improve the behaviour for specific applications.
Remember that this error only corresponds to about 5 yards in the entire circumference of the Earth.
Best Wishes |
|
|
XorpiZ Guest
|
|
Posted: Wed Nov 30, 2005 9:59 am |
|
|
Hmm thanks.. Kinda sucks though :/
But i guess we have to make our coordinates in 5454.15 format then. It should be able to handle that right? |
|
|
Ttelmah Guest
|
|
Posted: Wed Nov 30, 2005 10:22 am |
|
|
The error will still be present. Use as many digits in the input data as possible, and round the results to 6 digits in total. If you use the 'rounding' function (%g), the closest useable value will be given. If you look at (for instance), one 'half', this can be perfectly represented in FP. However if you look at one third, no matter how many digits the system has, there will still be an error. Remember also that if you now perform arithmetic, the error will grow depending on the function used...
This is _inherent_ in FP maths. This is why languages often have a 'currency' data type, that uses a scaled integer, to prevent this being a problem here.
If you need better levels of accuracy, either consider using a scaled integer, or a more powerful processor, and 8byte floats.
Best Wishes |
|
|
XorpiZ Guest
|
|
Posted: Wed Nov 30, 2005 10:26 am |
|
|
Okay, gotta take a look at it.
Thanks for the help! It's much appreciated. |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Wed Nov 30, 2005 12:03 pm |
|
|
Your floats are 4 bytes. In that size you could use use two 16 bit integers with a decimal point stuck between them instead. Then you would get out exactly what you put in. If you do math on the coordinates you would have to write your own math functions but that is not hard. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
XorpiZ Guest
|
|
Posted: Thu Dec 01, 2005 4:17 pm |
|
|
Nice tip Thank you |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Fri Dec 02, 2005 9:14 am |
|
|
Since this is latitude and longitude you could consider a base 60 arithmetic. Assuming you don't need to traverse a whole hemisphere you can store the longitude in one byte ( ignore the east west since the assumption is you stay in the same hemisphere) another byte for the minutes and another for seconds and a final byte for fractions of a second.
Similarly for latitude.
You could even stuff the East West into the most sig bit of the minutes byte since you know 0..59 is the max range and likewise the North South. Many GPS receivers will output deg , min. sec , fraction of a sec position format. You'll only need a simple add and subtract in base 60 and you'll have absolutely no loss of precision and on formatting the output you'll have the deg min and sec and fractions of a second already parsed for printing.
Mathematicians hate to hear binary float described as inaccurate the error is in transferring from decimal notation to binary notation.
1/3 in decimal is inaccurate since .333333 has to be cut off at some point. In base three is is absolutely precise ( 0.1 base3) It is the base switching that introduces the so called errors. No matter the base notation ( decimal binary) a whole number can be expressed fully given enough bytes. For a fractional number full expression is not a guarantee. 1/8 is good in both decimal and binary, but 1/3 is good in neither, 1/10 is good in decimal but not fully expressable in binary. |
|
|
|
|
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
|