C浮点精度

Jer*_*emy 2 c c++ floating-point floating-point-conversion

可能重复:
浮点比较

我对C/C++中float的准确性有疑问.当我执行以下程序时:

#include <stdio.h>

int main (void) {
    float a = 101.1;
    double b = 101.1;
    printf ("a: %f\n", a);
    printf ("b: %lf\n", b);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果:

a: 101.099998
b: 101.100000
Run Code Online (Sandbox Code Playgroud)

我相信浮点数应该是32位,所以应该足以存储101.1为什么?

pax*_*blo 11

只能表示恰好在IEEE754(至少对于单和双精度的二进制格式),如果他们可以从加入一起反转权力来构建数2(即,像,,,等等)受到可用的比特的数量为了精确.2-n11/21/41/65536

在浮点数(23位精度)双精度(52位精度)提供的缩放中,没有两种反转功率的组合可以精确到达101.1 .

如果你想要一个快速的教程,说明这两种倒置功能的工作原理,请参阅这个答案.

将该答案的知识应用于您的101.1数字(作为单个精确浮点数):

s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm    1/n
0 10000101 10010100011001100110011
           |  | |   ||  ||  ||  |+- 8388608
           |  | |   ||  ||  ||  +-- 4194304
           |  | |   ||  ||  |+-----  524288
           |  | |   ||  ||  +------  262144
           |  | |   ||  |+---------   32768
           |  | |   ||  +----------   16384
           |  | |   |+-------------    2048
           |  | |   +--------------    1024
           |  | +------------------      64
           |  +--------------------      16
           +-----------------------       2
Run Code Online (Sandbox Code Playgroud)

尾数的一部分实际上永远持续下去101.1:

mmmmmmmmm mmmm mmmm mmmm mm
100101000 1100 1100 1100 11|00 1100 (and so on).
Run Code Online (Sandbox Code Playgroud)

因此,它不是精确的问题,任何数量的有限位都不能完全代表IEEE754格式的数字.

使用这些位来计算实际数量(最接近的近似值),符号为正.指数为128 + 4 + 1 = 133 - 127 bias = 6,因此乘数为2 6或64.

尾数由1(隐式基数)加上(对于所有这些位,每个值为1 /(2 n),因为n从1开始并向右增加){1/2, 1/16, 1/64, 1/1024, 1/2048, 1/16384, 1/32768, 1/262144, 1/524288, 1/4194304, 1/8388608},.

当你添加所有这些,你得到1.57968747615814208984375.

当你乘以先前计算的乘数时64,你就得到了101.09999847412109375.

所有数字都是bc使用100个十进制数字的比例计算的,因此产生了大量的尾随零,因此数字应该非常准确.双重如此,因为我检查了结果:

#include <stdio.h>
int main (void) {
    float f = 101.1f;
    printf ("%.50f\n", f);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

给了我101.09999847412109375000....