与 Python、C 和 JavaScript 的舍入差异

问题描述

我正在尝试乘以数字,但不同的语言会产生不同的结果。这是数学问题:

x = 3.0524116
y = 57325
z = x * y

对于 Python(以及 JavaScript),z174979.49123897057。演示代码如下所示。

import numpy as np
x = np.float32(3.0524116)
y = np.uint32(57325)
z = x * y
print(z)

对于 C,z174979.500000。演示代码如下所示。

#include <stdio.h>
int main()
{
    float x = 3.0524116f;
    unsigned int y = 57325;
    float z = x * y;
    printf("%f\n",z);
    return 0; 
}

现在,当 z 在 C 中四舍五入为整数时,已经在 Python 中初始化的缓冲区溢出,整个事情都崩溃了……无论如何,这里发生了什么?为什么结果不一样?

解决方法

如果我在 C 中使用 float 而不是 double,我可以重现您的结果。 Python 的 float 类型和 JavaScript 的 Number 实际上是用 C double 实现的,因此如果您希望 C 的行为相同,请使用 double,而不是 float

,

您使用了错误的类型。

正如其他人指出的那样,Python 和 JavaScript 都使用 double 而不是 float。所以为了与 Python 和 Javascript 进行准确的比较,我尝试了这个程序:

#include <stdio.h>

int main()
{
    double x = 3.0524115349144454,y = 57325;
    printf("%.12lf\n",x * y);
    return 0;
}

当我运行它时,输出是 174979.491238970571。这与174979.49123897057 完全相同(除了 C 中的 1 个额外数字)。正如您所看到的,情况是一样的,您只是使用了错误的类型(很可能,如果您能在编辑中澄清这一点会很好)。

我还在 Python 和 Javascript 中运行了等效的程序,只是为了确保,输出是相同的。我运行了相同的 C 程序,只是我用 double 替换了 float,并且得到了 174979.500000000000 的输出。再说一次,这让我觉得你使用了 float,不过如果你能澄清一下就好了。

编辑:我刚刚注意到您所做的编辑。但是,C 测试和 Python 测试仍然不等价。在您的python示例中:

import numpy as np
x = np.float32(3.0524116)
y = np.uint32(57325)
z = x * y
print(z)

x * y 仍然返回双精度结果,然后将其存储在双精度 float z 中。要进行准确的测试,您必须将 z = x * y 替换为 z = np.float32(x * y)。当我尝试使用所需更改的 Python 程序时,我得到 174979.5,与使用 float 的 C 的结果相同。至于 Javascript,我不知道您是如何测试的,也不知道您如何在其中使用单精度 float。我对语言几乎一无所知,所以我不能说真的。