This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: float.hex discards sign from -nan
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: mark.dickinson, rhettinger, sree314, tim.peters, veky
Priority: normal Keywords:

Created on 2020-10-30 16:04 by sree314, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (5)
msg379979 - (view) Author: Sree (sree314) Date: 2020-10-30 16:04
float.hex(float.fromhex("-nan")) returns 'nan'.

PyOS_double_to_string seems to check only if it is a NaN, but ignores the sign (unlike its handling of inf a few lines below):

<https://github.com/python/cpython/blob/e9e7d284c434768333fdfb53a3663eae74cb995a/Python/pystrtod.c#L903>

Issue 5981 (https://bugs.python.org/issue5981) added the ability for fromhex to recognize -nan, but hex should probably have been updated at the same time.

Encountered when testing float implementations.
msg380007 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2020-10-30 22:26
Having fromhex() support signed NaNs was reasonable because it is a valid possible input; however, the case isn't as clear-cut for output. Since applications are allowed to ignore the sign bit, no application should rely on seeing a particular sign for a NaN.  

Also, existing applications may already have NaNs where the sign bit is set.  If we change the output, we could break their published examples and doctests.  So, this proposal may cause more harm than good.
msg380046 - (view) Author: Vedran Čačić (veky) * Date: 2020-10-31 08:44
inf and -inf are really two different values (in the scope of the standard). Same as 5. and -5., or even 0. and -0. They behave differently in some exactly specified operations, and it is useful.

Are there any exactly specified operations whose specifications require the unequal treatment of nans with + and - signs? I don't think so, since it goes against the whole idea of nan as an unspecified number. (If you want to track its _history_, that's what payload is for.) My interpretation is that nan can have a sign bit only so unary minus and absolute value can be implemented quicker (without having to check whether the input is nan) -- not because it carries any useful semantics within the standard.
msg380055 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2020-10-31 12:25
This isn't a bug: it was a deliberate decision, just like the choice to represent `-nan` as `nan` in `float.__repr__` was a deliberate decision. NaNs don't have a meaningful sign - they have a sign *bit*, but it's best to regard that as just an extra bit of metadata (like the payload bits).

IEEE 754 explicitly refuses to interpret the sign bit of a NaN: section 1.4 of the 2019 version of the standard says: "This standard does not specify [...] Interpretation of the sign and significand fields of NaNs."

As Vedran points out, infinities are a very different beast: the difference between negative infinity and positive infinity matters.

[Raymond]

> no application should rely on seeing a particular sign for a NaN

Yep, exactly.
msg380239 - (view) Author: Sree (sree314) Date: 2020-11-02 17:14
Thanks, all. I just wanted to know if this was a deliberate decision or an oversight. It also took me a while to realize it washex, and not fromhex.

That allows the current behaviour to be easily worked around in Python code, and a backwards compatible optional parameter to hex() might allow -nan in the future without breaking existing software.

Surprisingly, the standard does allow this [but this may not have been the intent] -- (Section 6.2) "Recognize that format conversions,
including conversions between supported formats and external representations as character sequences,
might be unable to deliver the same NaN." The conversion to character sequences text is key since I'm using a test harness written in Python that writes out and reads back text files containing float data.

Section 6.3 in the standard also adds more details on when the sign bit in NaNs is relevant.
History
Date User Action Args
2022-04-11 14:59:37adminsetgithub: 86376
2020-11-02 17:14:37sree314setmessages: + msg380239
2020-10-31 12:25:13mark.dickinsonsetstatus: open -> closed
resolution: not a bug
messages: + msg380055

stage: resolved
2020-10-31 08:44:52vekysetnosy: + veky
messages: + msg380046
2020-10-30 22:26:15rhettingersetnosy: + tim.peters
2020-10-30 22:26:02rhettingersetnosy: + rhettinger, mark.dickinson
messages: + msg380007
2020-10-30 16:04:29sree314create