-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LWG-2597 std::log misspecified for complex numbers #884
LWG-2597 std::log misspecified for complex numbers #884
Conversation
Partially address microsoft#67. Use `_Abs` and `_Copysign` instead of branching on `x < 0`, correctly treating negative zero as a negative number. This matters when branch cuts of a complex function lies on the real or the imaginary axis, where the results for positive zero and negative zero are different. The following cases are not fixed in this commit: * `pow` when the first argument is (negative - 0i). * (+/-∞ - 0i) and (-0 +/- ∞i).
For negative real number x, pow(x - 0i, y) and pow(x + 0i, y) are different: pow(x - 0i, y) = exp(y * log(x - 0i)) = exp(y * (log(|x|) - πi)) pow(x + 0i, y) = exp(y * log(x + 0i)) = exp(y * (log(|x|) + πi)) Thus pow(complex, real) couldn't simply return _Pow(real, real) when the imaginary part of the base is negative zero. This commit fixes this issue. This commit also modifies pow(complex, complex) to be consistent with pow(real, complex) when the base is a positive real number.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much for fixing all of these issues - I appreciate the incredibly thorough work. 😸 The product code looks good to me, and I have trivial stylistic suggestions for the test code, which I'll go ahead and push changes for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found a bug in the test code.
check_norm(finite, NaN) now fires an assertion as expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment nitpicks, but otherwise this looks great.
* Defend against definition of `signbit` as a function-like macro * Defend against improper promotions to `double` when computing `log(std::complex<float>)` in `/clr` mode.
Annotate workaround
Thank you for your contribution! I really can't overstate how much we appreciate help from domain experts. |
sqrt
,asin
,asinh
,acos
,acosh
,atan
andatanh
of (finite - 0i) and (-0 + finite i).pow(negative - 0i, y)
.proj(+/-∞ - 0i)
sqrt
of infinities.Fix #67.
Use
_Abs
and_Copysign
instead of branching onx < 0
, correctly treating negative zero as a negative number. This matters when branch cuts of a complex function lies on the real or the imaginary axis, where the results for positive zero and negative zero are different.