C中的double被初始化为舍入值

时间:2017-10-31 14:45:35

标签: c precision

使用这个简单的程序:

#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

int main(int argc, char* argv[])  {
    double a = 10.333300;
    double b = 10.333300000000000;
    double c = nextafter(a,a+0.5);
    double d = nextafter(b,a+0.5);
    printf("[%012.12f]\n[%012.12f]\n[%012.12f]\n[%012.12f]\n", a, b, c, d);
    return 0;
}

打印输出符合预期:

$ ./nextafter
[10.333300000000]
[10.333300000000]
[10.333300000000]
[10.333300000000]

但是,真正的价值并不是这些:

(gdb) p a
$1 = 10.333299999999999
(gdb) p b
$2 = 10.333299999999999
(gdb) p c
$3 = 10.333300000000001
(gdb) p d
$4 = 10.333300000000001

现在,这似乎是由the way floats and doubles are represented引起的,我正在使用带有旧RHEL的64位x86 VM。使用nextafter确实可以尽可能地解决问题,但它提出了一些问题:

无法将0.3333用“零填充”到右边的零,直到它形成一个有效的二进制数(在这种情况下,我猜是0.333300000000001)?即默认情况下可以使用nextafter吗?

有没有办法设置双默认精度(在这种情况下为10或11)?

是否有可以精确表示浮点数的架构?

或者说,为什么10.3333会立即四舍五入到10.3332(9)而不是将其四舍五入到nextafter版本?

1 个答案:

答案 0 :(得分:0)

发布的格式字符串正在使用:%012.12f

这会限制数字量太多。

建议使用格式字符串,如:%020.20f,然后输出将更符合您的要求。即。

[10.33329999999999948557]
[10.33329999999999948557]
[10.33330000000000126192]
[10.33330000000000126192]