Test case: https://godbolt.org/z/WqzW5b99E
#include <complex>
#include <cstdio>
using namespace std;
int main() {
using C = complex<double>;
const C t1 = C{1.0} / 0.0;
const C t2 = C{1.0} / C{0.0};
printf(" t1: (%g, %g)\n", t1.real(), t1.imag());
printf("t1 alt: (%g, -%g)\n", t1.real(), -t1.imag());
printf(" t2: (%g, %g)\n", t2.real(), t2.imag());
}
MSVC has always printed (this is not a regression):
t1: (inf, -nan(ind))
t1 alt: (inf, -nan)
t2: (nan, nan)
GCC/libstdc++ and Clang/libc++ print:
t1: (inf, -nan)
t1 alt: (inf, -nan)
t2: (inf, -nan)
This was originally reported as DevCom-10040631 and internal VSO-1539658 / AB#1539658 . The user is wondering whether this is a bug.
I've added "t1 alt" to show that "-nan(ind)" is just how MSVC likes to print negative NaN. Otherwise, the behavior for C{1.0} / 0.0 is consistent across implementations, and our implementation is just component-wise, so this is unsurprising:
|
template <class _Ty>
|
|
_NODISCARD _CONSTEXPR20 complex<_Ty> operator/(const complex<_Ty>& _Left, const _Ty& _Right) {
|
|
complex<_Ty> _Tmp(_Left);
|
|
_Tmp.real(_Tmp.real() / _Right);
|
|
_Tmp.imag(_Tmp.imag() / _Right);
|
|
return _Tmp;
|
|
}
|
For C{1.0} / C{0.0}, we go through:
|
} else if (_Rightimag == 0) { // set NaN result
|
|
this->_Val[_RE] = _Myctraits::_Nanv();
|
|
this->_Val[_IM] = this->_Val[_RE];
|
within the _Div() function:
|
template <class _Other>
|
|
_CONSTEXPR20 void _Div(const complex<_Other>& _Right) {
|
|
using _Myctraits = _Ctraits<_Ty>;
|
|
|
|
_Ty _Rightreal = static_cast<_Ty>(_Right.real());
|
|
_Ty _Rightimag = static_cast<_Ty>(_Right.imag());
|
|
|
|
if (_Myctraits::_Isnan(_Rightreal) || _Myctraits::_Isnan(_Rightimag)) { // set NaN result
|
|
this->_Val[_RE] = _Myctraits::_Nanv();
|
|
this->_Val[_IM] = this->_Val[_RE];
|
|
} else if ((_Rightimag < 0 ? -_Rightimag : +_Rightimag)
|
|
< (_Rightreal < 0 ? -_Rightreal : +_Rightreal)) { // |_Right.imag()| < |_Right.real()|
|
|
_Ty _Wr = _Rightimag / _Rightreal;
|
|
_Ty _Wd = _Rightreal + _Wr * _Rightimag;
|
|
|
|
if (_Myctraits::_Isnan(_Wd) || _Wd == 0) { // set NaN result
|
|
this->_Val[_RE] = _Myctraits::_Nanv();
|
|
this->_Val[_IM] = this->_Val[_RE];
|
|
} else { // compute representable result
|
|
_Ty _Tmp = (this->_Val[_RE] + this->_Val[_IM] * _Wr) / _Wd;
|
|
this->_Val[_IM] = (this->_Val[_IM] - this->_Val[_RE] * _Wr) / _Wd;
|
|
this->_Val[_RE] = _Tmp;
|
|
}
|
|
} else if (_Rightimag == 0) { // set NaN result
|
|
this->_Val[_RE] = _Myctraits::_Nanv();
|
|
this->_Val[_IM] = this->_Val[_RE];
|
|
} else { // 0 < |_Right.real()| <= |_Right.imag()|
|
|
_Ty _Wr = _Rightreal / _Rightimag;
|
|
_Ty _Wd = _Rightimag + _Wr * _Rightreal;
|
|
|
|
if (_Myctraits::_Isnan(_Wd) || _Wd == 0) { // set NaN result
|
|
this->_Val[_RE] = _Myctraits::_Nanv();
|
|
this->_Val[_IM] = this->_Val[_RE];
|
|
} else { // compute representable result
|
|
_Ty _Tmp = (this->_Val[_RE] * _Wr + this->_Val[_IM]) / _Wd;
|
|
this->_Val[_IM] = (this->_Val[_IM] * _Wr - this->_Val[_RE]) / _Wd;
|
|
this->_Val[_RE] = _Tmp;
|
|
}
|
|
}
|
|
}
|
Therefore we're deliberately returning (nan, nan) here.
Test case: https://godbolt.org/z/WqzW5b99E
MSVC has always printed (this is not a regression):
GCC/libstdc++ and Clang/libc++ print:
This was originally reported as DevCom-10040631 and internal VSO-1539658 / AB#1539658 . The user is wondering whether this is a bug.
I've added "t1 alt" to show that "-nan(ind)" is just how MSVC likes to print negative NaN. Otherwise, the behavior for
C{1.0} / 0.0is consistent across implementations, and our implementation is just component-wise, so this is unsurprising:STL/stl/inc/complex
Lines 1465 to 1471 in 1a20fe1
For
C{1.0} / C{0.0}, we go through:STL/stl/inc/complex
Lines 993 to 995 in 1a20fe1
within the
_Div()function:STL/stl/inc/complex
Lines 970 to 1009 in 1a20fe1
Therefore we're deliberately returning
(nan, nan)here.