gpt4 book ai didi

c++ - 不需要的部门运算符(operator)行为,我该怎么办?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:24:46 24 4
gpt4 key购买 nike

问题描述

在我的流体模拟过程中,物理时间以 0, 0.001, 0.002, ..., 4.598, 4.599, 4.6, 4.601, 4.602, ... 的形式前进。现在我想从这个时间序列中选择 time = 0.1, 0.2, ..., 4.5, 4.6, ... 然后做进一步的分析。所以我写了下面的代码来判断fractpart是否归零。

但令我非常惊讶的是,我发现以下两种划分方法得到了两种不同的结果,我该怎么办?

double param, fractpart, intpart;
double org = 4.6;
double ddd = 0.1;

// This is the correct one I need. I got intpart=46 and fractpart=0
// param = org*(1/ddd);

// This is not what I want. I got intpart=45 and fractpart=1
param = org/ddd;

fractpart = modf(param , &intpart);
Info<< "\n\nfractpart\t=\t"
<< fractpart
<< "\nAnd intpart\t=\t"
<< intpart
<< endl;

为什么会这样?
如果你们能容忍我一点,我可以大声喊道:“C++ 委员会可以对此做点什么吗?因为这令人困惑。” :)

获得正确余数以避免截断误差影响的最佳方法是什么? fmod 是更好的解决方案吗?谢谢

回应

的回答

大卫·施瓦茨

double aTmp = 1;
double bTmp = 2;
double cTmp = 3;
double AAA = bTmp/cTmp;
double BBB = bTmp*(aTmp/cTmp);
Info<< "\n2/3\t=\t"
<< AAA
<< "\n2*(1/3)\t=\t"
<< BBB
<< endl;

我两个都有,

2/3     =       0.666667
2*(1/3) = 0.666667

最佳答案

浮点值无法准确表示每个可能的数字,因此您的数字是近似值。这在计算中使用时会产生不同的结果。

如果您需要比较 float ,您应该始终使用较小的 epsilon 值而不是测试相等性。在你的情况下,我会四舍五入到最接近的整数(而不是向下舍入),从原始值中减去它,并将结果的 abs() 与 epsilon 进行比较。

如果问题是,为什么总和不同,简单的答案是它们是不同的总和。对于更长的解释,这里是所涉及数字的实际表示:

             org:  4.5999999999999996 = 0x12666666666666 * 2^-50
ddd: 0.10000000000000001 = 0x1999999999999a * 2^-56
1/ddd: 10 = 0x14000000000000 * 2^-49
org * (1/ddd): 46 = 0x17000000000000 * 2^-47
org / ddd: 45.999999999999993 = 0x16ffffffffffff * 2^-47

您会看到两个输入值都没有精确表示为 double 值,每个值都已向上或向下舍入到最接近的值。 org 已向下舍入,因为序列中的下一位将为 0。ddd 已向上舍入,因为该序列中的下一位将为 1。

因此,当执行数学运算时,舍入可以取消或累加,具体取决于运算以及原始数字的舍入方式。

在这种情况下,1/0.1 正好四舍五入到 10。

org 乘以 10 恰好四舍五入。

org 除以 ddd 恰好向下舍入(我说“恰好”,但你是用舍入后的数字除以向上舍入的数字,所以结果自然少了)。

不同的输入会有不同的舍入。

这只是一点错误,即使是很小的 epsilon 也可以很容易地忽略它。

关于c++ - 不需要的部门运算符(operator)行为,我该怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13918437/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com