2014-01-22 103 views
3
float x = 384.951257; 
std::cout << std::fixed << std::setprecision(6) << x << std::endl; 

输出是384.951263。为什么?我正在使用gcc。C++浮点控制台输出问题

+0

正如我所看到的'setprecision'不是std命名空间的成员。所以它不应该先跑。它如何为你提供产出? 是的,它是给出这个输出,因为编译器可能会舍去float值。 –

+3

@RavindraGupta'#包括'它就在那里。 – molbdnilo

回答

8

float通常只有32位。每个十进制数约3位(2 大致等于10 ),这意味着它不能可能代表小于约11个十进制数字更多,占它也需要表示其他信息,诸如大小,让我们说6-7个十进制数字。嘿,那就是你得到的!

检查例如维基百科的细节。

使用doublelong double更好的精度。 double是C++中的默认值。例如,文字3.14的类型是double

+0

优秀的解释!我只有一个问题,用'符号'或''来表示多少位小数。 (我想了解什么是11 - 7或8) –

+0

@Digital_Reality:例如http://en.wikipedia.org/wiki/IEEE_floating_point#Basic_formats –

+0

@ Cheersandhth.-Alf:这里的问题不是精确的,但并不是所有的小数都可以在二进制数系统中完全表示(请参阅我的答案)。使用'double'和'long double'也无济于事。 [见这里](http://ideone.com/8JzUpz)。 – legends2k

2

花车的分辨率有限。因此,当您将值分配到x时,它会变圆。

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数据类型通常被映射到binary32作为所谓由IEEE 754标准,具有32位,被分割为1个符号位,8指数位和23个有效数位(不包括隐藏/隐式位) 。因此,当转换为binary32时,我们必须计算高达24位。

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

整数部分384) = 1.1亿)(使用连续分割的通常的方法由2)

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

0.951257 * 2 = 1.902514

0.9 02514 * 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)。二进制的总数将是110000000.111100111000010);这需要24位。

将此转换回十进制会给你384 +(15585/16384)= 384.951232)。随着舍入模式(圆到最近)启用这个来,你看到,384.951263)。

这可以是verified here