Hi
The solution is BCD arithmetic where numbers are represented by strings.
Marek
Main Topics
Browse All Topics
Hi ...
I'm having problems dealing with floating point numbers in C.
The app we're developing requires great precision (sometimes to the 20th decimal point).
Problem is:
When I do this:
double abc;
abc = 8080.9940;
printf("Value: %.30lf\n", abc);
I get in the output:
Value: 8080.993999999999700000000
When I was expecting:
Value: 8080.994000000000000000000
Why this happens ? How can I avoid it ?
Thanks!
Bruno Monteiro Lopes
IST - Lx, Portugal
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
For example
http://developers.omnimark
Marek
Hi BrunoFLopes,
You avoid that problem if you leave it to the compiler how many decimals to display ("%f"). With your format you are forcing a certain number of decimals and depending on the implementation you will see diffrent values (my AIX xlc gives me 8080.993999999999687133822
BTW: why do you use the 'l' type? That's for long int types only.
======
Werner
Hi BrunoFLopes,
> The app we're developing requires great precision (sometimes to the
> 20th decimal point).
The best idea in your case is to use a library for arbitrary precision. Try the GNU Scientific Library:
http://www.gnu.org/directo
It's fast & proven code.
Cheers!
Stefan
A free library developed by an open source group is available, which deals with very large numbers and high precision arithmetic. This has been developed for the work related to cryptography.
Using their APIs you can do ANY precision arithmetic with floating point numbers.
Here are the urls:
http://swox.com/gmp/
ftp://ftp.gnu.org/gnu/gmp
-ssnkumar
You're asking printf to display 30 decimal places.
a double is probably 64 bits, with maybe 48 bits of precision.
48 bits is about 15 decimal digits.
Your number has 4 digits to the left of the decimal point, so you can expect about 11 digits to the right.
If you print out the number with %4.11lf format, then printf will round the number to the expected value.
By the way, you may want to re-think why you need 20 digits of precision-- there are darned few programs that really need this for a good reason.
Floating point numbers are represented as a mantissa and an exponent (which defines the position of the floating (decimal) point. The mantissa in turn is represented as a power of 2 (not a power of 10) as a consequence, some round decimal numbers will become repeating binimals. Consider 1b3/10b3 = 0.1b3 but 0.333...b10. I'd show you 1/10 -> b2 but my good calclulator is home and trying to do it on paper is making my head hurt.
BrunoFLopes,
Here is a good link which demonstrates the power (or weaknesses) of IEEE-754 floating points:
http://babbage.cs.qc.edu/c
Stefan
Business Accounts
Answer for Membership
by: KdoPosted on 2004-03-18 at 10:36:43ID: 10626337
Hi BrunoFLopes,
Floating point arithmetic isn't an "exact science" and you're seeing some of the effects of this.
One of two things is happening. The compiler is generating the value 8080.9940 by calculating it via 80809940/10000, or the conversion to ASCII is losing precision.
When I run the following test program, I get the same value that you do. However, the second line shows a pretty normal looking bit string. This suggests that the C library is losing precision when the value is converted for display.
#include <stdlib.h>
#include <stdio.h>
typedef union
{
double DV;
long IV;
} DI;
DI X;
int main()
{
X.DV = (double)8080.9940;
printf("Value: %.30lf\n", X.DV);
printf("Value: %16X\n", X.IV);
getchar ();
return 0;
}
Good Luck,
Kent