尝试复制 std::complex 行为,是标准库在骗我还是我错过了什么?

问题描述 投票:0回答:1

我正在尝试将

std::complex
编写为 HLSL 库。为此,我开始从算术运算符开始实现最基本的功能。对于有限的数字,一切都符合预期。但在无穷大时事情会变得很奇怪。我不会在这里接触任何 HLSL,它都是 C++。以下所有代码均在 Godbolt 上运行。

如果我运行以下代码

std::complex<float> a(-3.0, 4.0);
std::complex<float> inf(1.0f / 0.0f, 0.0f);
a /= inf;
std::cout << a << std::endl;

然后输出将是

(-0,0)
,这是预期的。为了在 HLSL 中实现这一点,我复制了
operator/=
的定义(在此处找到)(确保与 Godbolt 具有相同的 gcc 版本)。

现在运行此代码:

std::complex<float> a(-3.0, 4.0); std::complex<float> inf(1.0f / 0.0f, 0.0f); float r = a.real() * inf.real() + a.imag() * inf.imag(); float n = std::norm(inf); float imag = (a.imag() * inf.real() - a.real() * inf.imag()) / n; float real = r / n; std::cout << std::complex<float>(real, imag) << std::endl;

现在的输出(-nan, -nan)

,这与我刚刚做的
/=
得到的不同,但这是我阅读代码所期望的

标准库是否做了一些我在源代码中没有看到的事情,比如某种健全性检查?我错过了什么?

c++ std complex-numbers stdcomplex
1个回答
0
投票
我注意到 [complex.numbers.general]/3 表示“如果函数的结果未在数学上定义或不在其类型的可表示值范围内,则行为未定义”

如果我尝试编译:

const float infinity = 1/0;

gcc 14 给了我一个警告“警告:除以零 [-Wdiv-by-zero]”

clang 18 天“警告:除以零未定义 [-Wdivision-by-zero]”

© www.soinside.com 2019 - 2024. All rights reserved.