为什么scanf对大浮点数输错了?

Cha*_*yan -1 c floating-point gcc scanf

#include <stdio.h>

int main() { 
float k;
    scanf("%f", &k);
    printf("%f", k);
} 
Run Code Online (Sandbox Code Playgroud)

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

但如果我超过8位,即输入123456789输出123456792.

为什么会这样?那么有趣的事实是,如果我输入的任何数字,123456789并且123456796然后它总是显示123456792.

它是否与浮点数的8位小数精度有关?

dbu*_*ush 5

浮点类型的精度有限.对于float你的机器,它看起来是32位,它有24位精度(明确存储23,隐含1).这意味着大于~16000000的整数(需要超过24位存储)无法用此数据类型精确表示.

例如,您使用的值123456789具有以下二进制表示形式:

111 0101 1011 1100 1101 0001 0101
Run Code Online (Sandbox Code Playgroud)

该值占用27位,超过可用值.所以它四舍五入到可以用23位存储的最接近的值,即123456792.在二进制中:

111 0101 1011 1100 1101 0001 1000
Run Code Online (Sandbox Code Playgroud)

对于此值,未显式存储值为0的低3位.