来自类似浮点函数的不同结果
Different results from similar floating-point functions
所以我有 2 个函数应该做同样的事情
float ver1(float a0, float a1) {
float r0 = a0 - a1;
if (abs(r0) > PI) {
if (r0 > 0) {
r0 -= PI2;
} else {
r0 += PI2;
}
}
return r0;
}
float ver2(float a0, float a1) {
float a2 = a1 - PI2;
float r0 = a0 - a1;
float r1 = a0 - a2;
if (abs(r0) < abs(r1)) {
return r0;
}
if (abs(r0) > abs(r1)) {
return r1;
}
return 0;
}
注意:PI 和 PI2 是 pi 和 2*pi 的浮点常数
奇怪的是,有时它们会产生不同的结果,例如,如果您喂它们 0.28605145 和 5.9433694,那么第一个结果是 0.62586737,第二个结果是 0.62586755,我无法弄清楚是什么导致了这种情况。
如果你手动计算结果应该是什么,你会发现第二个答案是正确的。我在 2D 物理模拟中使用这个功能,真正奇怪的是,第一个答案(错误的答案)在那里工作,而第二个答案(正确的答案)让它表现得非常疯狂。来自未知来源的如此微小的差异和如此深远的影响:|
在这一点上,无论如何我都会切换到矩阵,但这种奇怪的情况让我很好奇,有人知道发生了什么吗?
float
的精度通常约为 24 位,或大约 7 位小数。
您正在减去两个数量级相似的数字(第一个是r0+PI2
,第二个是a1-PI2
),因此正在经历显著性损失 - 结果的几个最高有效位为零,因此剩余的位更少来表示差异。这就是为什么答案只匹配大约 6 位小数的原因。
如果需要更高的精度,则double
或 32 位或更大的定点表示可能比 float
更合适。还有一些任意精度的库可用,例如 GMP,它可以以您需要的所有精度表示数字,尽管算术会比内置类型慢得多。
使用fabs()
函数而不是abs()
abs()
因为它只适用于整数。将abs()
与浮点一起使用时,您会得到奇怪和错误的结果。
浮点数的行为不像数学实数。每 2 和可能导致"错误"。所以我不会仅仅因为一个例子就称第一个正确和第二个不正确。如果你想保持较小的误差,你需要小心你对浮点数所做的每一个动作。
如果数字的 abs 在同一范围内,则误差通常较小。如果范围不同,则误差往往更大。
例如,10000000.0 + 0.1 - 10000000.0
几乎从不0.1
。
如果您知道输入的范围,则可以调整代码以减少错误。
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- C++Brute Force攻击函数不会返回结果
- 如何从递归函数中完全返回,该函数给出了每个函数结果的累积相加?
- C++ SSE 内部函数:将结果存储在变量中
- c++ lambda:柯里和函数:使用按值捕获与按引用捕获返回不同的结果
- C++ 随机数生成器:尝试将结果作为向量获取,但通过制作 void 函数来执行此操作而出现错误
- C++ 获取函数在常量引用中按值返回的结果
- C++ 犰狳库中的sort_index()函数给出了错误的结果
- 从返回 std::optional of std::vector 的函数中获取结果到调用方
- 类中静态函数C++意外结果
- 为什么函数 tellg() 没有返回好的结果?
- 模板函数意外的结果
- 使用具有默认参数的函数模板进行 decltype 会使结果混乱(一个有趣的问题或 gcc 的错误)
- lambda 函数未显示正确的结果
- 为什么我可以改变常量对象中的成员变量,这是返回常量对象函数的结果?
- 我们如何并行运行算法的 n 个实例并以有效的方式计算结果函数的平均值?
- Fmod 函数清楚地输出一个预期的双精度值,但 if(fmod == 预期的双精度值)的计算结果不是 true
- 有没有办法将 for 循环结果返回到像三元运算符这样的函数中?
- 为什么这个涉及 std::enable_if 的模板元函数会产生不希望的结果?
- 使用类似的比较函数时,在 c++ 中为 std:sort 获得不同的结果