void main()
{
float a = 0.7;
if (a < 0.7)
printf("c");
else
printf("c++");
}
在0.7的上述问题中,将打印“c”,但对于0.8,将打印“c ++”。为什么呢?
如何以二进制形式表示浮动?
在某些地方,提到内部0.7将存储为0.699997,但0.8存储为0.8000011。为什么这样?
答案 0 :(得分:12)
基本上使用float,你得到32位编码
VALUE = SIGN * MANTISSA * 2 ^ (128 - EXPONENT)
32-bits = 1-bit 23-bits 8-bits
并存储为
MSB LSB
[SIGN][EXPONENT][MANTISSA]
因为你只得到23位,这就是你可以存储的“精度”。如果您试图表示在基数2中不合理(或重复)的分数,则位序列将在第23位“舍入”。
0.7 base 10是7/10,二进制是0b111 / 0b1010你得到:
0.1011001100110011001100110011001100110011001100110011... etc
由于这种情况重复,因此在固定精度下无法准确表示它。该 同样适用于0.8,二进制是:
0.1100110011001100110011001100110011001100110011001101... etc
要查看这些数字的固定精度值是什么,你必须以你的位数“切断它们”并进行数学计算。唯一的技巧是你隐含的前导1并没有存储,所以你在技术上获得了额外的精度。由于舍入,最后一位将为1或0,具体取决于截断位的值。
因此,0.7的值实际上是11,744,051 / 2 ^ 24(无舍入效应)= 0.699999988,而0.8的值实际上是13,421,773 / 2 ^ 24(四舍五入)= 0.800000012。
这就是它的全部内容:)
答案 1 :(得分:10)
对此的一个很好的参考是What Every Computer Scientist Should Know About Floating-Point Arithmetic。如果需要,可以使用更高精度类型(例如double)或二进制编码十进制(BCD)库来获得更好的浮点精度。
答案 2 :(得分:4)
内部代表是IEE754。
您也可以使用this calculator将十进制转换为浮点数,我希望这有助于理解格式。
答案 3 :(得分:0)
float
将按照IEEE 754:1位中的符号进行存储,8表示偏置指数,其余存储小数部分。
将数字表示为浮点数作为数字线上的点,相隔一定距离;通常,小数部分将落在这些点之间,并且将使用最近的表示;这会导致您描述的违反直觉的结果。
"What every computer scientist should know about floating point arithmetic"应该详细回答您的所有问题。
答案 4 :(得分:0)
如果您想知道C(以及几乎所有语言)中的float / double是如何呈现的,请参考标准浮点运算(IEEE 754)http://en.wikipedia.org/wiki/IEEE_754-2008
Using single-precision floats as an example, here is the bit layout:
seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm meaning
31 0 bit #
s = sign bit, e = exponent, m = mantissa
答案 5 :(得分:0)
另一个很好的资源,可以看到浮点数如何在计算机中存储为二进制文件,这是Wikipedia在IEEE-754上的页面。
答案 6 :(得分:0)
C / C ++中的浮点数以IEEE-754标准格式表示。互联网上有很多文章,它们比我在这里描述得更详细,如何用二进制表示一个浮点。对IEEE-754的简单搜索应该可以解释这个谜团。
答案 7 :(得分:0)
0.7是一个数字文字;它的值是数学实数0.7,四舍五入到最接近的双精度值。
初始化浮点数a = 0.7后,a的值为0.7舍入为浮点数,即实数0.7,舍入到最接近的double值,四舍五入到最接近的浮点值。除了一个巨大的巧合,你不会指望a等于0.7。
“if(a&lt; 0.7)”将0.7舍入为双倍然后浮动,数字0.7舍入为double。似乎在0.7的情况下,舍入产生较小的数字。并且在0.8的相同实验中,将0.8舍入到浮点将产生大于0.8的数字。
答案 8 :(得分:-2)
浮点比较不可靠,无论你做什么。您应该使用阈值容忍比较/ epsilon浮点比较。
尝试IEEE-754 Floating-Point Conversion,看看你得到了什么。 :)