【问题标题】:Why is scanf taking the wrong input for large float numbers? [duplicate]为什么 scanf 为大浮点数输入错误的输入? [复制]
【发布时间】:2018-01-24 16:47:54
【问题描述】:
#include <stdio.h>

int main() { 
float k;
    scanf("%f", &k);
    printf("%f", k);
} 

在这个简单的程序中,当我输入一个最多包含 8 位数字的数字时,它会正确显示。

但如果我超过 8 位数字,即输入 123456789,则输出为 123456792

为什么会这样?有趣的事实是,如果我输入介于123456789123456796 之间的任何数字,那么它总是显示123456792

与浮点数的 8 位精度有关吗?

【问题讨论】:

标签: c gcc floating-point scanf


【解决方案1】:

浮点类型的精度有限。对于您机器上的float,它看起来是 32 位,它具有 24 位精度(23 位显式存储,1 位隐含)。这意味着大于 ~16000000 的整数(需要超过 24 位来存储)不能用这种数据类型精确表示。

例如,您使用的值 123456789 的二进制表示为:

111 0101 1011 1100 1101 0001 0101

此值占用 27 位,超出可用位。所以四舍五入到23位能存储的最接近的值,即123456792。二进制:

111 0101 1011 1100 1101 0001 1000

对于这个值,没有显式存储值为 0 的低 3 位。

【讨论】:

  • Off by 1:~16000000 大约是正确的,但典型的 float 具有 24 位精度。 23个是直接编码的,1个是隐含的。整数到 float 的第一次不精确转换是 16,777,217 (0x1000001),一个 25 位整数。
  • @chux 很好。已更新以反映。
猜你喜欢
  • 1970-01-01
  • 2015-03-15
  • 2017-08-12
  • 1970-01-01
  • 1970-01-01
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
相关资源
最近更新 更多