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.
Created on 2015年01月07日 16:33 by ethan.furman, last changed 2022年04月11日 14:58 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| math_inf_nan.patch | mark.dickinson, 2015年01月07日 18:42 | review | ||
| math_inf_nan2.patch | mark.dickinson, 2015年01月07日 19:27 | review | ||
| math_inf_nan3.patch | mark.dickinson, 2015年01月07日 20:02 | review | ||
| math_inf_nan4.patch | mark.dickinson, 2015年01月08日 17:40 | review | ||
| Messages (26) | |||
|---|---|---|---|
| msg233580 - (view) | Author: Ethan Furman (ethan.furman) * (Python committer) | Date: 2015年01月07日 16:33 | |
Proposal:
math.nan = float('nan')
math.inf = float('inf')
Guido's approval:
https://mail.python.org/pipermail/python-ideas/2015-January/030775.html
Followup question:
Do we add a math.neginf, or somesuch, for float('-inf')? Or just use -math.inf?
|
|||
| msg233581 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2015年01月07日 16:42 | |
> Do we add a math.neginf, or somesuch, for float('-inf')? Or just use -math.inf?
I would prefer to only add inf.
It looks like float("-inf") and -float("inf") have exactly the same IEEE 754 representation (at least on my x86_64 CPU):
>>> struct.pack("d", float("-inf")) == struct.pack("d", -float("inf"))
True
|
|||
| msg233582 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月07日 16:57 | |
Sounds good to me. > Do we add a math.neginf IMO no: -inf should be fine. |
|||
| msg233583 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月07日 16:58 | |
> float("-inf") and -float("inf") have exactly the same IEEE 754 representation
Indeed: there's only one negative infinity (and only one positive infinity) in IEEE 754 binary64 format.
|
|||
| msg233585 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月07日 17:07 | |
Implementation suggestion: if possible, use the _Py_dg_stdnan and _Py_dg_infinity functions from Python/dtoa.c. These are a little safer than the Py_NAN and Py_HUGE_VAL macros, and will give results consistent with the float("inf") and float("nan") constructions. |
|||
| msg233588 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2015年01月07日 17:25 | |
Oh, NaN can be signed?
>>> struct.pack("d", float("nan"))
b'\x00\x00\x00\x00\x00\x00\xf8\x7f'
>>> struct.pack("d", float("-nan"))
b'\x00\x00\x00\x00\x00\x00\xf8\xff'
>>> struct.pack("d", -float("nan"))
b'\x00\x00\x00\x00\x00\x00\xf8\xff'
>>> struct.pack("d", -float("-nan"))
b'\x00\x00\x00\x00\x00\x00\xf8\x7f'
Why does Python return the same representation for positive and negative NaN?
>>> float("nan")
nan
>>> float("-nan")
nan
|
|||
| msg233591 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月07日 18:18 | |
> Why does Python return the same representation for positive and negative NaN? History, perhaps? In any case, the sign of a NaN isn't useful information in the same way that the sign of an infinity is. The IEEE 754 standard explicitly refuses to attach any meaning to the sign bit of a NaN. And if we were aiming for a full and faithful representation of NaNs, we'd want to output the payload, too (which is just about as meaningless / meaningful as the sign bit). |
|||
| msg233593 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2015年01月07日 18:25 | |
There are several different NaNs.
>>> x = struct.unpack('d', b'\x00\x00\x00\x00\x00\x00\xf8\x7f')[0]
>>> x
nan
>>> x == x
False
>>> struct.pack('d', x)
b'\x00\x00\x00\x00\x00\x00\xf8\x7f'
>>> x = struct.unpack('d', b'\x00\x00\x00\x00\x00\x00\xf9\x7f')[0]
>>> x
nan
>>> x == x
False
>>> struct.pack('d', x)
b'\x00\x00\x00\x00\x00\x00\xf9\x7f'
Interesting, but 0*inf and inf-inf return values with the same representation as float('-nan'), not float('nan').
>>> inf = float("inf")
>>> struct.pack('d', 0*inf)
b'\x00\x00\x00\x00\x00\x00\xf8\xff'
>>> struct.pack('d', inf-inf)
b'\x00\x00\x00\x00\x00\x00\xf8\xff'
>>> struct.pack('d', float('nan'))
b'\x00\x00\x00\x00\x00\x00\xf8\x7f'
>>> struct.pack('d', float('-nan'))
b'\x00\x00\x00\x00\x00\x00\xf8\xff'
|
|||
| msg233594 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2015年01月07日 18:27 | |
By tweaking the grammar we can have math.-inf. |
|||
| msg233595 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月07日 18:27 | |
> but 0*inf and inf-inf return values with the same representation as float('-nan'), not float('nan')
Right: that's because Intel's "default" NaN (i.e., the float it produces as a result of any invalid operation) has its sign bit set.
|
|||
| msg233596 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月07日 18:27 | |
> By tweaking the grammar we can have math.-inf. AAAARRGH! |
|||
| msg233598 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月07日 18:42 | |
Here's a patch. |
|||
| msg233601 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月07日 19:27 | |
Thanks for the review comments. Here's an updated patch taking the review comments into account (and fixing the spelling of PY_NAN, which should have been Py_NAN). |
|||
| msg233602 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月07日 20:02 | |
One more patch, fixing a misplaced period. |
|||
| msg233607 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2015年01月07日 22:09 | |
"History, perhaps? In any case, the sign of a NaN isn't useful information in the same way that the sign of an infinity is. The IEEE 754 standard explicitly refuses to attach any meaning to the sign bit of a NaN. And if we were aiming for a full and faithful representation of NaNs, we'd want to output the payload, too (which is just about as meaningless / meaningful as the sign bit)."
So I understand that adding a math.neg_nan would be useless. As adding one constant per possible "NaN" value :-) If I recall correctly the IEEE 754 standard, there is not single NaN value, but a range of NaN.
"Two kinds of NaN: a quiet NaN (qNaN) and a signaling NaN (sNaN). A NaN may carry a payload that is intended for diagnostic information indicating the source of the NaN. The sign of a NaN has no meaning, but it may be predictable in some circumstances." says Wikipedia.
Well, the current definition of math.nan makes sense, it's the same value than float("nan").
Note: On python-ideas, I asked if math.nan and math.inf should be singleton (as it was requested for float("0.0") in issue #4024). The answer is no.
|
|||
| msg233630 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月08日 08:58 | |
I have an updated patch taking into account the most recent review comments (for which thanks!), but it's at home; I'll upload it this evening (UTC+00:00). |
|||
| msg233674 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月08日 17:40 | |
New patch, addressing review comments. |
|||
| msg233692 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2015年01月08日 22:41 | |
Except of my small suggestion on the doc (see the review), math_inf_nan4.patch looks good to me. |
|||
| msg233720 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2015年01月09日 07:16 | |
May be make math.inf and math.nan special objects so that for all x (except inf and nan): x < math.inf x > -math.inf not (x < math.nan) not (x > math.nan) |
|||
| msg233737 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2015年01月09日 08:57 | |
2015年01月09日 8:16 GMT+01:00 Serhiy Storchaka <report@bugs.python.org>: > May be make math.inf and math.nan special objects so that for all x (except inf and nan): What do you mean? Implement a subtype of float and override some methods? > x < math.inf > x > -math.inf It's already the case for int, float and decimal.Decimal. > not (x < math.nan) > not (x > math.nan) Comparison to nan always return False. I would be better to raise an error when nan is compared to other numbers (I mean operations like a>b, not a==b), but Python was not designed like that (nor the IEEE 754?). >>> sorted((nan, 1, nan, 2)) [nan, 1, nan, 2] Sorting with NaN is a common issue :-/ See for example: https://stackoverflow.com/questions/4240050/python-sort-function-breaks-in-the-presence-of-nan Anyway, changing NaN behaviour is out of the scope of this issue! |
|||
| msg233842 - (view) | Author: Roundup Robot (python-dev) (Python triager) | Date: 2015年01月11日 11:55 | |
New changeset cf4bf577749c by Mark Dickinson in branch 'default': Issue #23185: add math.inf and math.nan constants. https://hg.python.org/cpython/rev/cf4bf577749c |
|||
| msg233843 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月11日 11:56 | |
Committed. Thanks for all the helpful review comments! |
|||
| msg233894 - (view) | Author: Guido van Rossum (gvanrossum) * (Python committer) | Date: 2015年01月12日 22:41 | |
Should inf and nan be added to cmath too? It has e and pi and isnan() and isinf()...
Also complex(0, math.nan) a value that is printed as "nanj" and complex("nanj") parses and returns such a value, so the point could be made that there should be a constant named complex.nanj.
|
|||
| msg233912 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2015年01月13日 09:07 | |
Guido van Rossum added the comment:
> Should inf and nan be added to cmath too? It has e and pi and isnan() and isinf()...
>
> Also complex(0, math.nan) a value that is printed as "nanj" and complex("nanj") parses and returns such a value, so the point could be made that there should be a constant named complex.nanj.
Since it's a different module and we are talking about more and
different constants, I suggest to open a new issue.
|
|||
| msg233917 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月13日 09:35 | |
> Should inf and nan be added to cmath too? Hmm; probably, yes. I'll open an issue. > so the point could be made that there should be a constant named complex.nanj Yes, I suppose it could (along with infj, of course). I don't like it much, and I suspect it would get almost no uses. complex(0, inf) and complex(0, nan) seem like good enough spellings. |
|||
| msg233920 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2015年01月13日 09:37 | |
Opened issue #23229. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:58:11 | admin | set | github: 67374 |
| 2015年01月13日 09:37:33 | mark.dickinson | set | messages: + msg233920 |
| 2015年01月13日 09:35:45 | mark.dickinson | set | messages: + msg233917 |
| 2015年01月13日 09:07:12 | vstinner | set | messages: + msg233912 |
| 2015年01月12日 22:41:31 | gvanrossum | set | nosy:
+ gvanrossum messages: + msg233894 |
| 2015年01月11日 11:56:31 | mark.dickinson | set | status: open -> closed resolution: fixed messages: + msg233843 stage: needs patch -> resolved |
| 2015年01月11日 11:55:40 | python-dev | set | nosy:
+ python-dev messages: + msg233842 |
| 2015年01月11日 00:05:27 | ethan.furman | set | nosy:
+ lemburg, rhettinger, eric.smith, stutzbach |
| 2015年01月09日 08:57:16 | vstinner | set | messages: + msg233737 |
| 2015年01月09日 07:16:11 | serhiy.storchaka | set | messages: + msg233720 |
| 2015年01月08日 22:41:09 | vstinner | set | messages: + msg233692 |
| 2015年01月08日 17:40:20 | mark.dickinson | set | files:
+ math_inf_nan4.patch messages: + msg233674 |
| 2015年01月08日 08:58:49 | mark.dickinson | set | messages: + msg233630 |
| 2015年01月07日 22:09:05 | vstinner | set | messages: + msg233607 |
| 2015年01月07日 20:02:37 | mark.dickinson | set | files:
+ math_inf_nan3.patch messages: + msg233602 |
| 2015年01月07日 19:27:27 | mark.dickinson | set | files:
+ math_inf_nan2.patch messages: + msg233601 |
| 2015年01月07日 18:42:47 | mark.dickinson | set | files:
+ math_inf_nan.patch assignee: mark.dickinson messages: + msg233598 keywords: + patch |
| 2015年01月07日 18:27:45 | mark.dickinson | set | messages: + msg233596 |
| 2015年01月07日 18:27:27 | mark.dickinson | set | messages: + msg233595 |
| 2015年01月07日 18:27:06 | pitrou | set | nosy:
+ pitrou messages: + msg233594 |
| 2015年01月07日 18:25:27 | serhiy.storchaka | set | nosy:
+ serhiy.storchaka messages: + msg233593 |
| 2015年01月07日 18:18:08 | mark.dickinson | set | messages: + msg233591 |
| 2015年01月07日 17:25:57 | vstinner | set | messages: + msg233588 |
| 2015年01月07日 17:07:00 | mark.dickinson | set | messages: + msg233585 |
| 2015年01月07日 16:58:50 | mark.dickinson | set | messages: + msg233583 |
| 2015年01月07日 16:57:53 | mark.dickinson | set | nosy:
+ mark.dickinson messages: + msg233582 |
| 2015年01月07日 16:55:21 | berker.peksag | set | components:
+ Library (Lib) stage: needs patch |
| 2015年01月07日 16:42:15 | vstinner | set | nosy:
+ vstinner messages: + msg233581 |
| 2015年01月07日 16:33:44 | ethan.furman | create | |