从 C++11 开始,我们可以在编译时进行浮点数学运算。C++23 和 C++26 添加了constexpr
一些函数,但不是全部。
constexpr
一般来说,浮点数学很奇怪,因为结果并不完全准确。然而,constexpr
代码应该始终提供一致的结果。C++ 如何解决这个问题?
constexpr
浮点数学
是如何工作的?constexpr
,而其他功能则不然(例如std::nearbyint
)我正在执行这个问题的代码:为什么以下代码的输出不为零?
#include <stdio.h>
int main (void)
{
double A = 373737.0;
double B;
B = A*A*A + 0.37/A - A*A*A - 0.37/A;
printf("The value of B is %f.\n", B);
}
Run Code Online (Sandbox Code Playgroud)
每个主流 x86 编译器的每个优化设置都会给出输出-0.000001
。当我使用当前的 clang 15.0.0 时,我-O0
也得到了这一点。
但是,使用 14.0.0 版本以上的 clang 和-O1
to进行编译-O3
会给出输出-1.000001
。为什么会发生这种情况?这是一个已知的错误?
Godbolt 为了您的方便:https ://godbolt.org/z/M5j3fGhWf
考虑以下函数:
static inline float Eps(const float x) {
const float eps = std::numeric_limits<float>::epsilon();
return (1.0f + eps) * x - x;
}
float Eps1() {
return Eps(0xFFFFFFp-24f);
}
float Eps2() {
const float eps = std::numeric_limits<float>::epsilon();
const float x = 0xFFFFFFp-24f;
return (1.0f + eps) * x - x;
}
Run Code Online (Sandbox Code Playgroud)
在-O2
with中-std=c++20
,这两个函数都编译为一个函数,movss
后跟一个ret
针对 x86 的 using clang 16.0.0 和mov
一个bx
针对 ARM 的 with gcc 11.2.1。为 ARM 生成的程序集与返回值 ~5.96e-8 一致,但为 x86 生成的程序集则不然。 …