<complex>: Many functions produce incorrect results for complex NaNs and infinities
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 11.2k
- Forks
- 1.7k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 22
Description
Describe the bug
Many functions in <complex> don't produce the correct result for complex NaNs and infinities as specified in C Annex G.
Command-line test case
This is not a comprehensive list of incorrect behavior. There are tests (which currently fail) in libcxx for the requirements.
G:\Temp>type complex4.cpp
#include <cmath>
#include <complex>
#include <iostream>
#include <limits>
using namespace std;
template <typename T>
void print_result(const char* expr, const T& expected, const T& actual) {
cout << expr << "\n"
<< " Expected: " << expected << "\n"
<< " Actual: " << actual << "\n"
<< "\n";
}
#define EVAL_AND_PRINT(expr, expected) print_result(#expr, expected, expr)
constexpr double operator""_pi(long double x) { return static_cast<double>(x) * 3.1415926535897932; }
constexpr double operator""_pi(unsigned long long x) { return static_cast<double>(x) * 3.1415926535897932; }
int main() {
constexpr double inf = numeric_limits<double>::infinity();
constexpr double nan = numeric_limits<double>::quiet_NaN();
EVAL_AND_PRINT(complex(inf, nan) * complex(1.0, 0.0), complex(inf, nan));
EVAL_AND_PRINT(complex(inf, nan) / complex(1.0, 0.0), complex(inf, nan));
EVAL_AND_PRINT(sinh(complex(inf, nan)), complex(inf, nan));
EVAL_AND_PRINT(cosh(complex(0.0, inf)), complex(nan, 0.0));
EVAL_AND_PRINT(tanh(complex(inf, nan)), complex(1.0, 0.0));
EVAL_AND_PRINT(acos(complex(0.0, nan)), complex(0.5_pi, nan));
EVAL_AND_PRINT(atanh(complex(inf, nan)), complex(0.0, nan));
EVAL_AND_PRINT(exp(complex(inf, inf)), complex(inf, nan));
}
G:\Temp>cl /EHsc /std:c++17 /W4 /WX .\complex4.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.26.28806 版
版权所有(C) Microsoft Corporation。保留所有权利。
complex4.cpp
Microsoft (R) Incremental Linker Version 14.26.28806.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:complex4.exe
complex4.obj
G:\Temp>.\complex4.exe
complex(inf, nan) * complex(1.0, 0.0)
Expected: (inf,nan)
Actual: (nan,-nan(ind))
complex(inf, nan) / complex(1.0, 0.0)
Expected: (inf,nan)
Actual: (nan,nan)
sinh(complex(inf, nan))
Expected: (inf,nan)
Actual: (inf,inf)
cosh(complex(0.0, inf))
Expected: (nan,0)
Actual: (-nan(ind),-nan(ind))
tanh(complex(inf, nan))
Expected: (1,0)
Actual: (nan,nan)
acos(complex(0.0, nan))
Expected: (1.5708,nan)
Actual: (nan,nan)
atanh(complex(inf, nan))
Expected: (0,nan)
Actual: (nan,nan)
exp(complex(inf, inf))
Expected: (inf,nan)
Actual: (inf,inf)
STL version
Microsoft Visual Studio Community 2019
版本 16.6.1
Additional context
Should we bypass the checks and/or use faster but less stable algorithms when CX_LIMITED_RANGE, /fp:fast or -ffast-math is on? (especially for the "cheap" operations like operator* and norm)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the supplied complex4.cpp reproducer and the libcxx tests mentioned in the issue, then inspect the implementation and its handling of NaNs and infinities. Done means the affected functions produce the C Annex G results covered by those tests, including the listed operations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100