我在x86 VM(32位)上发现了以下程序:
#include <stdio.h>
void foo (long double x) {
int y = x;
printf("(int)%Lf = %d\n", x, y);
}
int main () {
foo(.9999999999999999999728949456878623891498136799780L);
foo(.999999999999999999972894945687862389149813679978L);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
产生以下输出:
(int)1.000000 = 1
(int)1.000000 = 0
Run Code Online (Sandbox Code Playgroud)
编译器做了什么来允许这种情况发生?
我发现这个不变,因为我正在追踪为什么下面的程序没有0按照我的预期产生(使用19 9秒产生0我预期的):
int main () {
long double x = .99999999999999999999L; /* 20 9's */
int y = x;
printf("%d\n", y);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我试图计算结果从预期切换到意外时的值时,我得出了这个问题的常数.
如何以任意精度水平进行比较,以便我可以看到两个数字相同?在Python中,我会使用类似的函数round(),所以我在Rust中寻找相同的东西.
例如,我有:
let x = 1.45555454;
let y = 1.45556766;
Run Code Online (Sandbox Code Playgroud)
在我的情况下,它们相似,最多2位小数.因此x,y为了进行比较,它将变为1.46.我可以格式化这些,但肯定是慢的,什么是检查等价的最好的Rust方法,所以:
if x == y { // called when we match to 2 decimal places}
Run Code Online (Sandbox Code Playgroud)
进一步阐明问题并给出一些背景.这实际上是为了美元和美分的准确性.所以通常python会使用round()函数及其所有问题.是的我知道浮点表示的局限性.计算金额有两个函数,我以美元计算,需要将美分部分处理到最近的便士.
问社区的原因是我怀疑如果我自己动手,它可能会达到性能而且就是这个方面 - 这就是我为什么要使用Rust,所以我在这里.另外我在Rust文档中看到了一个名为round()的东西,但它似乎与pythons版本不同,它采用零参数.