简体   繁体   English

c语言中浮点数四舍五入背后的逻辑是什么?

[英]What logic works behind the rounding off of floating point number in c language?

I have written a program in c language to roundoff floating point number but the output of the program does not follow any logic.我用c语言编写了一个程序来四舍五入浮点数,但程序的输出不遵循任何逻辑。 The code is-->代码是-->

#include<stdio.h>

int main(){
    float a=2.435000;
    float b=2.535000;
    float c=2.635000;
    float d=2.735000;
    float e=2.835000;
    //Rounding off the floating point numbers to 2 decimal places
    printf("%f  %.2f\n",a,a);
    printf("%f  %.2f\n",b,b);
    printf("%f  %.2f\n",c,c);
    printf("%f  %.2f\n",d,d);
    printf("%f  %.2f\n",e,e);


    return 0;
}

OUTPUT:输出:

2.435000 2.43 2.435000 2.43

2.535000 2.54 2.535000 2.54

2.635000 2.63 2.635000 2.63

2.735000 2.73 2.735000 2.73

2.835000 2.84 2.835000 2.84

All the floating numbers have same pattern of digits ie they are in the form of 2.x35000 where x is different in different numbers.所有浮点数都具有相同的数字模式,即它们采用 2.x35000 的形式,其中 x 在不同数字中不同。 I am not getting why they are showing different behaviour while getting roundoff ,either they should give 2.x3 or 2.x4 but for different x it is giving different value.我不明白为什么他们在四舍五入时表现出不同的行为,他们应该给出 2.x3 或 2.x4,但对于不同的 x,它给出不同的值。

What is the logic behind this?这背后的逻辑是什么?

It looks to you and me like 2.435 is a nice, round decimal fraction.在你我看来,2.435 是一个不错的整数小数。
It looks to you and me like if we rounded it to two places, we'd get 2.44.在你我看来,如果我们把它四舍五入到两个地方,我们会得到 2.44。
But most computers do not use decimal fractions internally, and the ones you and I use definitely do not.但是大多数计算机内部使用小数,而你我使用的绝对使用小数。 They use binary fractions, and binary fractions can be surprising.他们使用二进制分数,而二进制分数可能会令人惊讶。

Internally, it turns out that the number 2.435 cannot be represented exactly in binary.在内部,事实证明数字 2.435 不能用二进制精确表示。 As a float , it's represented internally as a binary fraction that's equivalent to 2.434999942779541015625.作为float ,它在内部表示为二进制分数,相当于 2.434999942779541015625。 That's pretty close to 2.435, but you can see that if you round it to two places, you get 2.43 instead.这非常接近 2.435,但是您可以看到,如果将其四舍五入到两个位置,则会得到 2.43。

The same sorts of argument explain your other results.同样的论证解释了你的其他结果。 2.635 is really 2.6349999904632568359375, so it rounds to 2.63. 2.635 实际上是 2.6349999904632568359375,所以它四舍五入到 2.63。 But 2.535 is 2.5350000858306884765625, so it rounds to 2.54, as you expect.但是 2.535 是 2.5350000858306884765625,所以它四舍五入到 2.54,正如你所期望的。

Why can't we get closer to, say, 2.435?为什么我们不能接近,比如说,2.435? As I said, internally it's a binary fraction equivalent to 2.434999942779541015625.正如我所说,在内部它是一个相当于 2.434999942779541015625 的二进制小数。 The actual IEEE-754 single-precision representation is 0x401bd70a , which works out to 0x0.9bd70a × 2² , or 0.60874998569488525390625 × 2 2 .实际的IEEE-754 单精度表示是0x401bd70a ,结果为0x0.9bd70a × 2² ,或 0.60874998569488525390625 × 2 2 But if we "add 1" to it, that is, if we make it the tiniest bit bigger that we can, the next float value is 0x401bd70b , which is 0x0.9bd70b or 0.608750045299530029296875 × 2 2 , which is 2.4350001811981201171875, which ends up being a little bit farther away from 2.435.但是,如果我们“加1”来了,那就是,如果我们把它最小的有点大了,我们就可以了,接下来的float值是0x401bd70b ,这是0x0.9bd70b或0.608750045299530029296875×2 2,这是2.4350001811981201171875,从而结束了离 2.435 有点远。 (It's actually over three times as far away. The first number is off by 0.000000057; the second one is off by 0.000000181.) (实际上是三倍多。第一个数字相差 0.000000057;第二个数字相差 0.000000181。)

You can read more about the sometimes surprising properties of binary floating-point numbers at these other "canonical" SO questions:您可以在这些其他“规范”SO 问题中阅读有关二进制浮点数有时令人惊讶的属性的更多信息:

Two other interesting questions that were asked about them -- just in the past couple of days -- were:关于他们的另外两个有趣的问题——就在过去几天——是:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM