Skip to content

Conversation

@bjodah
Copy link
Member

@bjodah bjodah commented Jan 25, 2018

Python doesn't have a math.sign function, it does have a copysign function though, however, just wrapping copysign would not give the right answer for sign(0) (hence the use of the ternary operator).

@ylemkimon
Copy link
Member

math.copysign(1, S.NaN) returns -1.0 and math.copysign(1, float('nan')) returns 1.0.

@bjodah
Copy link
Member Author

bjodah commented Jan 27, 2018

Nice catch! (I'm surprised that copysign isn't returning NAN here). But isn't that a "bug" in math.copysign?

@ylemkimon
Copy link
Member

It's probably because it just copies the sign bit and NaN has a sign bit.

@bjodah
Copy link
Member Author

bjodah commented Jan 27, 2018

I tracked down the issue. The problem does not lie in sympy, but rather mpmath:

>>> import math
>>> from mpmath.libmp.libmpf import fnan
>>> from mpmath.libmp import to_float
>>> math.copysign(1.0, to_float(fnan))
-1.0
>>> math.copysign(1.0, float('nan'))
1.0

One possible work-around would be to define the method __float__ in sympy.core.numbers.NaN to return float('nan'). But I think that is a separate issue.

@bjodah
Copy link
Member Author

bjodah commented Feb 7, 2018

@ylemkimon since the nan issue is mpmath related, I think this PR is as good as it gets in that respect. What do you think? (and do you have any other comments?)

Copy link
Member

@ylemkimon ylemkimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant a discrepancy between SymPy's sign returning NaN for NaN and Python's copysign returning +-1 for NaN, but it's an implementation issue, not a code printer should handle. LGTM 😄

@bjodah bjodah merged commit a671c3f into sympy:master Feb 9, 2018
@bjodah bjodah deleted the pycode-sign branch February 9, 2018 15:56
aaron-skydio added a commit to aaron-skydio/sympy that referenced this pull request Mar 11, 2025
This is half issue, half PR - I'm not 100% sure exactly how this should be correctly implemented, and I'm not necessarily going to have time to test this further, but the fix is small enough and the code change demonstrates the issue better than an issue would.

As I understand it, `sympy.sign` is defined to return 0 for 0.  Other code printers also implement it this way, see for example sympy#14010.  Rust's `signum` returns 1 or -1 for 0 (depending on the sign of the 0, for floats with signed zeroes), which isn't correct.
aaron-skydio pushed a commit to aaron-skydio/sympy that referenced this pull request Mar 11, 2025
This is half issue, half PR - I'm not 100% sure exactly how this should be correctly implemented, and I'm not necessarily going to have time to test this further, but the fix is small enough and the code change demonstrates the issue better than an issue would.

As I understand it, `sympy.sign` is defined to return 0 for 0.  Other code printers also implement it this way, see for example sympy#14010.  Rust's `signum` returns 1 or -1 for 0 (depending on the sign of the 0, for floats with signed zeroes), which isn't correct.
aaron-skydio pushed a commit to aaron-skydio/sympy that referenced this pull request Mar 11, 2025
This is half issue, half PR - I'm not 100% sure exactly how this should be correctly implemented, and I'm not necessarily going to have time to test this further, but the fix is small enough and the code change demonstrates the issue better than an issue would.

As I understand it, `sympy.sign` is defined to return 0 for 0.  Other code printers also implement it this way, see for example sympy#14010.  Rust's `signum` returns 1 or -1 for 0 (depending on the sign of the 0, for floats with signed zeroes), which isn't correct.
aaron-skydio added a commit to aaron-skydio/sympy that referenced this pull request Mar 11, 2025
This is half issue, half PR - I'm not 100% sure exactly how this should be correctly implemented, and I'm not necessarily going to have time to test this further, but the fix is small enough and the code change demonstrates the issue better than an issue would.

As I understand it, `sympy.sign` is defined to return 0 for 0.  Other code printers also implement it this way, see for example sympy#14010.  Rust's `signum` returns 1 or -1 for 0 (depending on the sign of the 0, for floats with signed zeroes), which isn't correct.
firatbezir pushed a commit to firatbezir/sympy that referenced this pull request Mar 21, 2025
This is half issue, half PR - I'm not 100% sure exactly how this should be correctly implemented, and I'm not necessarily going to have time to test this further, but the fix is small enough and the code change demonstrates the issue better than an issue would.

As I understand it, `sympy.sign` is defined to return 0 for 0.  Other code printers also implement it this way, see for example sympy#14010.  Rust's `signum` returns 1 or -1 for 0 (depending on the sign of the 0, for floats with signed zeroes), which isn't correct.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants