C++ 为什么浮点变量以一种奇怪的方式在点后剪切数字来保存值?

C++ 为什么浮点变量以一种奇怪的方式在点后剪切数字来保存值?,c++,floating-point,ieee-754,floating-point-precision,digits,C++,Floating Point,Ieee 754,Floating Point Precision,Digits,我有一个简单的代码行: float val = 123456.123456; 当我打印此val或查找范围时,它存储值123456.13 好的,没关系,它不能在4个字节中存储点后的所有数字,但为什么它在点后加13呢?应该是12点吗 (在win32上使用vc++2010 express)尝试打印std::numeric\u limits::digits10的值。这大致上就是说一个浮点数在基数10中的精度有多高。您试图超过它,因此您正在经历精度损失(这意味着超出有效数字的数字实际上没有意义) 请参见

我有一个简单的代码行:

float val = 123456.123456;
当我打印此val或查找范围时,它存储值123456.13

好的,没关系,它不能在4个字节中存储点后的所有数字,但为什么它在点后加13呢?应该是12点吗


(在win32上使用vc++2010 express)

尝试打印
std::numeric\u limits::digits10的值。这大致上就是说一个浮点数在基数10中的精度有多高。您试图超过它,因此您正在经历精度损失(这意味着超出有效数字的数字实际上没有意义)


请参见,例如,它完全依赖于编译器。在GCC中检查它。它应该是xxx.12

存储在
val
中的值等于
123456.125
。您得到的是
.13
,因为您正在舍入它:

float val = 123456.123456;
printf("%.4f %.2f\n", val, val);
输出:
123456.1250 123456.13


在这种情况下,应该使用double来避免截断。编译器还应该警告您:警告C4305:“初始化”:从“双精度”截断为“浮点”

在二进制中,123456.123456是11110001000000.00011111001。。。(无限)。它四舍五入到11110001001000000.001或123456.125。打印时四舍五入为123456.13。

当表示为浮点数时,数字的指数为16(即该值是其尾数乘以2^16,或65536)。尾数就变成了

123456.123456 / 65536 = 1.8837909462890625
为了适应32位浮点,尾数被截断为23位,因此现在它变成
1.883791
。当乘以
65536
时,它变为
123456.125

注意小数点后第三位的<代码> 5代码>:使用的C++输出程序将其循环,使最终的数字看起来像“代码> 123456.13 < < /P>”。 编辑舍入解释:(里克·里根的评论)

舍入首先在二进制(到24位)、十进制到二进制转换中发生,然后在
printf
中发生到十进制。存储值为1.111000100100000001 x 2^16=1.8837909698486328125 x 2^16=123456.125。它打印为123456.13,但仅仅是因为VisualC++使用了“从零开始的半圆”四舍五入。 瑞克也有一个朋友


如果您想使用其他数字及其浮点表示,这里有一个。

如果内部使用的格式是IEEE-754,那么它不应该依赖于编译器。我认为我们给出了“依赖于编译器”两种不同的含义;我和其他人所理解的是,你说的是“编译器之间的差异很正常”。你是说这是编译器特有的错误吗?请你再解释一下。。我无法特别理解这一行“当表示为浮点数时,您的数字的指数为16”。为什么需要它?@RasmiRanjanNayak 32位浮点表示为23位尾数、7位二进制指数和符号位。从逻辑上讲,您可以将原始数字除以2,然后增加指数,直到小数点前唯一剩余的数字是
1
。对于
123456.123456
,需要16个分区。@dasblinkenlight充其量这个描述是误导性的。舍入首先在二进制(到24位)中发生,在十进制到二进制转换中发生,然后在printf中发生到十进制。存储值为1.111000100100000001 x 2^16=1.8837909698486328125 x 2^16=123456.125。它打印为123456.13,但仅仅是因为Visual C++使用了“从零开始的半圆”四舍五入(见我的文章)@ RKEGRANWOW,好文章!感谢您的参考,我在答案中添加了您的评论以使其更加完整。非常感谢你的帮助!谢谢大家的回答。我现在明白了。我只是觉得它应该在一点之后去掉超限的数字,而不是四舍五入。