C ++浮点控制台输出问题

时间:2014-01-22 13:06:40

标签: c++ io

float x = 384.951257;
std::cout << std::fixed << std::setprecision(6) << x << std::endl;

输出为384.951263。为什么?我正在使用gcc。

3 个答案:

答案 0 :(得分:8)

float通常只有32位。每个十进制数约为3位(2 10 大致等于10 3 ),这意味着它不可能代表超过大约11个十进制数字,并考虑其他信息也需要表示,例如幅度,比方说6-7个十进制数字。嘿,那就是你得到的!

检查例如维基百科了解详情。

使用doublelong double可获得更高的精确度。 double是C ++中的默认值。例如,文字3.14的类型为double

答案 1 :(得分:2)

浮点数的分辨率有限。因此,当您将值分配给x时,它会四舍五入。

答案 2 :(得分:2)

这里的所有答案都说这个问题是由浮点数和它们的容量引起的,但这些只是实现细节;问题比这更深刻。使用二进制数系统表示十进制数时会发生此问题。甚至像0.1)10 is not precisely representable in binary那样简单,因为it can only represent those numbers as a finite fraction where the denominator is a power of 2。不幸的是,这并不包括可以在基数10中表示为有限分数的大多数数字,如0.1。

单精度float数据类型通常被映射到IEEE 754标准调用的binary32,具有32位,分为1个符号位,8个指数位和23个有效位(排除隐藏/隐含位)。因此,当转换为binary32时,我们要计算最多24位。

这里的其他答案逃避了所涉及的实际计算,我会尽力去做。解释了此方法in greater detail here。因此,让我们将实数转换为二进制数:

  

整数部分384) 10 = 110000000) 2 (使用通常的连续除法方法2)

     

小数部分0.951257) 10 可以通过连续乘以2并取整数部分来转换

     

0.951257 * 2 = 1.902514

     

0.902514 * 2 = 1.805028

     

0.805028 * 2 = 1.610056

     

0.610056 * 2 = 1.220112

     

0.220112 * 2 = 0.440224

     

0.440224 * 2 = 0.880448

     

0.880448 * 2 = 1.760896

     

0.760896 * 2 = 1.521792

     

0.521792 * 2 = 1.043584

     

0.043584 * 2 = 0.087168

     

0.087168 * 2 = 0.174336

     

0.174336 * 2 = 0.348672

     

0.348672 * 2 = 0.697344

     

0.697344 * 2 = 1.394688

     

0.394688 * 2 = 0.789376

收集二进制的已分数部分我们已经0.111100111000010) 2 。二进制的总数为110000000.111100111000010) 2 ;这需要24位。

将此转换为十进制将为您提供384 +(15585/16384)= 384.951232) 10 。在启用舍入模式(舍入到最近)的情况下,您会看到,384.951263) 10

这可以是verified here