相关疑难解决方法(0)

constexpr 浮点数学有何含义?

从 C++11 开始,我们可以在编译时进行浮点数学运算。C++23 和 C++26 添加了constexpr一些函数,但不是全部。

constexpr一般来说,浮点数学很奇怪,因为结果并不完全准确。然而,constexpr代码应该始终提供一致的结果。C++ 如何解决这个问题?

问题

  • constexpr浮点数学 是如何工作的?
    • 所有编译器的结果都相同吗?
    • 对于同一编译器,编译时和运行时的结果是否相同?
  • 为什么有些功能有效constexpr,而其他功能则不然(例如std::nearbyint

c++ floating-point constexpr c++23 c++26

34
推荐指数
2
解决办法
2532
查看次数

clang 14.0.0 浮点优化

我正在执行这个问题的代码:为什么以下代码的输出不为零?

#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 和-O1to进行编译-O3会给出输出-1.000001。为什么会发生这种情况?这是一个已知的错误?

Godbolt 为了您的方便:https ://godbolt.org/z/M5j3fGhWf

c floating-point optimization clang

9
推荐指数
1
解决办法
1070
查看次数

如果数学移至内联函数,为什么 C++ 舍入行为(对于编译时常量)会发生变化?

考虑以下函数:

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)

-O2with中-std=c++20,这两个函数都编译为一个函数,movss后跟一个ret针对 x86 的 using clang 16.0.0 和mov一个bx针对 ARM 的 with gcc 11.2.1。为 ARM 生成的程序集与返回值 ~5.96e-8 一致,但为 x86 生成的程序集则不然。 …

c++ floating-point clang compiler-optimization clang++

7
推荐指数
1
解决办法
257
查看次数