开发者

float numbers in c [Xcode IDE]

开发者 https://www.devze.com 2023-02-28 05:58 出处:网络
I have started to learn c language but the problem is that I\'m confused about how to use float numbers. I am using Xcode as IDE. Here are the results that got me confused:

I have started to learn c language but the problem is that I'm confused about how to use float numbers. I am using Xcode as IDE. Here are the results that got me confused:

float x1 = 1.123456789123456789f;  
double x2 = 1.123456789123456789f;  
float x3 = 987654321.123456789f;  
double x4 = 987654321.123456789f;  

开发者_如何学JAVAprintf("x1 = %.20f\n", x1);  
printf("x2 = %.20f\n", x2);  
printf("x3 = %10.10f\n", x3);  
printf("x4 = %10.10f\n", x4);  

The output is:

x1 = 1.12345683574676513672  
x2 = 1.12345683574676513672  
x3 = 987654336.0000000000  
x4 = 987654336.0000000000  

The question is, why x1, x2 lose their float digits after 1.12345678? And why x3 and x4 are truncated?


The basic problem here is that floating point numbers only have a limited precision: they can only represent that many significant digits before they run out of space. It does not matter if those digits are before the decimal point or after it, the total number of significant digits matters. Note that this issue is not restricted to C, it can be seen in all languages/environments that use floating point numbers.

double should be able to store about twice as many digits as float, but all your floating point literals are float literals. Remove the f postfix on the double lines to actually use all the bits available for a double.


What you're missing is that you're putting each of your numbers through 2 base conversions, and x2 and x4 also through a widening type conversion.

First of all you have decimal literals, which the compiler converts to binary fractions of type float, which have a precision of 23 binary digits (equivalent to about 7.2 decimal digits) and cannot accurately represent most decimal fractions, even those that fit into their precision. Then x2 and x4 are assigned to double variables, but since everything that does not fit into 23 binary digits has already been cropped, they don't magically regain the precision that was present in the literals.

Then, you convert the binary fractions back to decimal via printf, and get the previously mention ca. 7.2 decimal digits correct, and everything after that reflects the representational rounding error created by the base conversion.

It's basically the same as if you try to convert 1/3 to a decimal fraction 0.333 and back to a proper fraction 333/1000 - hey, why isn't it 1/3?

Read the floating-point guide for more information.

0

精彩评论

暂无评论...
验证码 换一张
取 消