我试图用完整的python重现一个C++高精度计算,但我得到了一个轻微的差异,我不明白为什么.

Python :

from decimal import *
getcontext().prec = 18
r = 0 + (((Decimal(0.95)-Decimal(1.0))**2)+(Decimal(0.00403)-Decimal(0.00063))**2).sqrt()
# r = Decimal('0.0501154666744709107')

C++:

#include <iostream>
#include <math.h>

int main()
{
    double zx2 = 0.95;
    double zx1 = 1.0;
    double zy2 = 0.00403;
    double zy1 = 0.00063;
    double r;
    r = 0.0 + sqrt((zx2-zx1)*(zx2-zx1)+(zy2-zy1)*(zy2-zy1));
    std::cout<<"r = " << r << " ****";

    return 0;
}
// r = 0.050115466674470907 ****

在python的末尾出现了1个,但在c++中没有,为什么?在python中更改精度不会改变任何事情(我已经try 过),因为1在"舍入"之前.

Python : 0.0501154666744709107 
C++   : 0.050115466674470907

编辑:

推荐答案

这种差异的根源是Python Decimal遵循了更现代的IBM的General Decimal Arithmetic Specification.

然而,在C++中也存在通过long double格式对80位"extended precision"的支持.

作为参考,标准IEEE-754浮点double包含53位精度.

下面是问题中的C++示例,使用long doubles重构:

#include <iostream>
#include <math.h>
#include <iomanip>

int main()
{
    long double zx2 = 0.95;
    long double zx1 = 1.0;
    long double zy2 = 0.00403;
    long double zy1 = 0.00063;
    long double r;
    r = 0.0 + sqrt((zx2-zx1)*(zx2-zx1)+(zy2-zy1)*(zy2-zy1));
    std::fixed;
    std::cout<< std::setprecision(25) << "r = " << r << " ****";  //25 floats
    // prints "r = 0.05011546667447091067728042 ****"
    return 0;
}

Python相关问答推荐

Plotly Dash Creating Interactive Graph下拉列表

如何在达到end_time时自动将状态字段从1更改为0

numpy.unique如何消除重复列?

Python—转换日期:价目表到新行

Python—为什么我的代码返回一个TypeError

在numpy数组中寻找楼梯状 struct

如何求相邻对序列中元素 Select 的最小代价

查看pandas字符列是否在字符串列中

在我融化极点数据帧之后,我如何在不添加索引的情况下将其旋转回其原始形式?

504未连接IB API TWS错误—即使API连接显示已接受''

如何编辑此代码,使其从多个EXCEL文件的特定工作表中提取数据以显示在单独的文件中

如何获得满足掩码条件的第一行的索引?

分解polars DataFrame列而不重复其他列值

在任何要保留的字段中添加引号的文件,就像在Pandas 中一样

替换包含Python DataFrame中的值的<;

pyspark where子句可以在不存在的列上工作

在FastAPI/Starlette中使用WebSockets时如何运行后台任务?

S最大值除以最小值,然后减1的结果是什么?

通过外键Django创建从一个字段到其他字段的 Select 列表

如何更改GEKKO变量在解算为稳定状态后的MV状态?