C 浮点控制台输出问题

C++ floating-point console output issue

本文关键字:输出 出问题 控制台      更新时间:2023-10-16
float x = 384.951257;
std::cout << std::fixed << std::setprecision(6) << x << std::endl;

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

float通常只有32位。每小十位数约3位(2 10 大致等于10 3 ),这意味着它不能代表大约11个小数位数,并对其他信息进行核算还需要表示诸如大小之类的,例如6-7个小数位数。嘿,那就是你得到的!

检查,例如Wikipedia有关详细信息。

使用doublelong double,以提高精度。double是C 中的默认值。例如,字面的3.14是类型double

浮子的分辨率有限。因此,当您对x的值进行构想。

在这里所有答案都会说问题是由于浮点数及其容量所致,但这只是实现细节;这个问题比这更深。当使用二进制数字系统表示十进制数字时,就会发生此问题。即使是像0.1) 10 那样简单的东西也不是二进制中的代表,因为它只能将这些数字表示为有限分数,其中分母的幂为2。不幸的是,这不包括大多数大多数在基本10中可以表示为有限分数的数字,例如0.1。

单精度float数据类型通常被映射到IEEE 754标准所调用的 binary32 ,具有32位,将32位分为1个符号位,8个指数位,23个exponent bit和23个显着位(排除隐藏/隐式位)。因此,转换为二进制32时,我们必须计算24位。

这里的其他答案避免了所涉及的实际计算,我将尝试做到这一点。此方法将在此处更详细说明。因此,让我们将实数转换为二进制号码:

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

分数零件0.951257) 10 可以通过2次乘法转换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 。二进制总数为1100000.111100111000010) 2 ;根据需要,这有24位。

将其转换回小数将为您提供384 (15585/16384)= 384.951232) 10 。通过圆形模式(圆形到最近),您看到的是384.951263) 10 。

这可以在此处进行验证。