如何找到浮点数的最短表示形式

How can I find the shortest representation of a floating-point number

提问人:DarkAtom 提问时间:5/10/2021 更新时间:5/11/2021 访问量:373

问:

如果我尝试打印具有最大精度的类型浮点值,例如:

printf("%.100e", FLT_MIN);

我明白了:

1.1754943508222875079687365372222456778186655567720875215087517062784172594547271728515625000000000000e-38

但是,如果我尝试打印这样的东西(我更改了尾数的最后一位数字):

float x = 1.1754943508222875079687365372222456778186655567720875215087517062784172594547271728515610e-38f;
printf("%.100e", x);

然后输出是一样的:

1.1754943508222875079687365372222456778186655567720875215087517062784172594547271728515625000000000000e-38

这是因为我输入的值没有确切的表示,所以它被舍入了。

问题是:我怎样才能找到四舍五入到相同数字的最短值(以数字表示)?

c 点浮 点精度

评论

0赞 Eric Postpischil 5/10/2021
在 Stack Overflow 中搜索“grisu3”或“dragon4”会显示相关信息。
1赞 Eric Postpischil 5/10/2021
特别是参见 Printing Floating-Point Numbers Quickly and Accurate with Integers,尽管我认为可能还有更多最近的工作。请注意,实现算法需要以多种方式掌握浮点运算的一些技能(除了熟悉浮点标准外,还要了解编译器在浮点运算下的行为方式)。
2赞 Eric Postpischil 5/10/2021
如果你想要一个简短、缓慢和愚蠢的实现,那么显然你可以用它来将数字打印到一个具有一个有效数字 () 的缓冲区,将该数字转换回浮点类型,看看它是否相同。如果没有,请再试一位数字。重复上述步骤,直到该号码在往返行程中幸存下来。这当然要求您的 C 实现在这些转换中提供正确的舍入。苹果的图书馆确实如此。C 实现建议使用它(最多为实现支持的任何格式所需的位数),但不需要它。snprintf%.1g
0赞 chux - Reinstate Monica 5/10/2021
“我怎样才能找到四舍五入到相同数字的最短值(以数字表示)?” --> 用于开始步骤。也许可以用更少的钱做,但没有比这更多的情况了。其他方法,请看和.printf("%.e\n", FLT_DECIMAL_DIG-1, some_float);"%g""%a"
0赞 Eric Postpischil 5/10/2021
更正:上面的“The C implementation recommend it”应为“The C standard recommend it”。

答:

1赞 tstanisl 5/11/2021 #1

您可以使用 C99 中引入的十六进制浮点数。

#include <stdio.h>

int main() {
    float x = 1.1754943508222875079687365372222456778186655567720875215087517062784172594547271728515625000000000000e-38;
    printf("%a\n", x); // prints 0x1p-126
    float hx = 0x1p-126;
    printf("%a\n", hx); // prints 0x1p-126
}

评论

0赞 DarkAtom 5/11/2021
是的,但我知道,但我希望它以 10 为基数(E 表示法)。