相关疑难解决方法(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++中是否允许浮点表达式收缩?

浮点表达式有时可以在处理硬件上收缩,例如使用融合乘法和加法作为单个硬件操作.

显然,使用这些不仅仅是一个实现细节,而是由编程语言规范控制.具体来说,C89标准不允许这样的收缩,而在C99中,只要定义了某些宏,就允许它们.请参阅此SO答案中的详细信息.

但是C++怎么样?浮点收缩是不允许的?某些标准允许吗?普遍允许吗?

c++ floating-point fma

6
推荐指数
1
解决办法
471
查看次数

Clang 融合乘加取决于表达式参数的恒定性

如clang 14.0.0 浮点优化的答案所示,自版本 14 起,Clang 即使对于在编译时执行的常量计算也应用融合乘法加法 (FMA) 指令。

同时,我们可以观察到结果取决于表达式参数的形式恒定性:

#include <stdio.h>

int main() {
    const float A = 2.1f;
    const float B = 0.1f;
          float C = 0.1f;
    float V = A * B - A * B;
    float W = A * C - A * C;
    printf( "%g %g", V, W );
}
Run Code Online (Sandbox Code Playgroud)

在 Clang 中,程序打印0 1.49011e-10,在线演示:https://godbolt.org/z/a3fcYG7ob

从汇编代码可以看出, 和V都是W在编译时求值的。是否有一些规则规定只能W使用 FMA 指令进行评估?

添加-mno-fma用于禁用 FMA 指令的命令行选项不会改变结果中的任何内容。

c floating-point optimization clang fma

5
推荐指数
0
解决办法
197
查看次数

标签 统计

floating-point ×4

c ×2

c++ ×2

clang ×2

fma ×2

optimization ×2

c++23 ×1

c++26 ×1

constexpr ×1