c++ - 类似浮点函数的不同结果

标签 c++ floating-accuracy

所以我有 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的 float

奇怪的是,有时它们会产生不同的结果,例如,如果您给它们提供 0.28605145 和 5.9433694,那么第一个结果为 0.62586737,第二个结果为 0.62586755,我不知道是什么原因造成的。

如果您手动计算结果应该是什么,您会发现第二个答案是正确的。我在 2d 物理 sim 中使用这个功能,真正奇怪的是第一个答案(错误的)在那里工作,而第二个(正确的)让它表现得非常疯狂。来自未知来源的如此微小的差异和如此深远的影响:|

在这一点上,无论如何我都会切换到矩阵,但这种奇怪的情况让我很好奇,有人知道发生了什么吗?

最佳答案

float 通常具有大约 24 位的精度,或大约 7 位小数。

您正在减去两个大小相似的数字(第一个为 r0+PI2,第二个为 a1-PI2),因此损失了significance - 结果的几个最高有效位为零,因此剩下更少的位来表示差异。这就是答案仅匹配小数点后 6 位的原因。

如果您需要更高的精度,double 或 32 位或更大的定点表示可能比 float 更合适。还有任意精度的库可用,例如 GMP ,它可以以您需要的所有精度表示数字,尽管算术运算会比内置类型慢得多。

关于c++ - 类似浮点函数的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12421536/

相关文章:

C99 - 关于浮点舍入模式排序的保证

PHP 数多于 10 位小数

math - float 学有问题吗?

java - 如何在 Java 中以近似值设置 float 或 double 的自定义小数位数

javascript - 大数字在 JavaScript 中被错误地四舍五入

c++ - 如何正确编写在 Debug模式下加载而不会崩溃的 C++ DLL

c++ - 为什么我的单个字符不止一个字符长?

c++ - 无链表的无锁编程

android - 为什么我在编译时不能将 android-platform 设置为低于 22?

c++ - C1083 : Cannot open include file: . .. : No such file or directory?