Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #7066
| From | Chris Torek <nospam@torek.net> |
|---|---|
| Newsgroups | comp.lang.python |
| Subject | Re: float("nan") in set or as key |
| Date | 2011-06-06 01:56 +0000 |
| Organization | None of the Above |
| Message-ID | <ishc5302ne4@news7.newsguy.com> (permalink) |
| References | <4de6df06$0$29996$c3e8da3$5496439d@news.astraweb.com> <ish1fg029vl@news1.newsguy.com> <mailman.2475.1307315609.9059.python-list@python.org> <4dec2ba6$0$29996$c3e8da3$5496439d@news.astraweb.com> |
>> On Mon, Jun 6, 2011 at 8:54 AM, Chris Torek <nospam@torek.net> wrote:
>>> A signalling NaN traps at (more or less -- details vary depending on
>>> FPU architecture) load time.
>On Mon, 06 Jun 2011 09:13:25 +1000, Chris Angelico wrote:
>> Load. By this you mean the operation of taking a bit-pattern in RAM and
>> putting it into a register? So, you can calculate 0/0, get a signalling
>> NaN, and then save that into a memory variable, all without it trapping;
>> and then it traps when you next perform an operation on that number?
I mean, if you think of the FPU as working (in principle) with
either just one or two registers and a load/store architecture, or
a tiny little FPU-stack (the latter is in fact the case for Intel
FPUs), with no optimization, you get a trap when you attempted to
load-up the sNaN value in order to do some operation on it. For
instance, if x is an sNaN, "y = x + 1" turns into "load x; load
1.0; add; store y" and the trap occurs when you do "load x".
In article <4dec2ba6$0$29996$c3e8da3$5496439d@news.astraweb.com>,
Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:
>The intended behaviour is operations on "quiet NANs" should return NANs,
>but operations on "signalling NANs" should cause a trap, which can either
>be ignored, and converted into a quiet NAN, or treated as an exception.
>
>E.g. in Decimal:
>
>>>> import decimal
>>>> qnan = decimal.Decimal('nan') # quiet NAN
>>>> snan = decimal.Decimal('snan') # signalling NAN
>>>> 1 + qnan
>Decimal('NaN')
>>>> 1 + snan
>Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File "/usr/local/lib/python3.1/decimal.py", line 1108, in __add__
> ans = self._check_nans(other, context)
> File "/usr/local/lib/python3.1/decimal.py", line 746, in _check_nans
> self)
> File "/usr/local/lib/python3.1/decimal.py", line 3812, in _raise_error
> raise error(explanation)
>decimal.InvalidOperation: sNaN
Moreover:
>>> cx = decimal.getcontext()
>>> cx
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, capitals=1, flags=[], traps=[DivisionByZero, Overflow, InvalidOperation])
>>> cx.traps[decimal.InvalidOperation] = False
>>> snan
Decimal("sNaN")
>>> 1 + snan
Decimal("NaN")
so as you can see, by ignoring the InvalidOperation exception, we
had our sNaN converted to a (regular, non-signal-ing, "quiet") NaN,
and 1 + NaN is still NaN.
(I admit that my mental model using "loads" can mislead a bit since:
>>> cx.traps[decimal.InvalidOperation] = True # restore trapping
>>> also_snan = snan
>>>
A simple copy operation is not a "load" in this particular sense,
and on most real hardware, one just uses an ordinary 64-bit integer
memory-copying operation to copy FP bit patterns from one place to
another.)
There is some good information on wikipedia:
http://en.wikipedia.org/wiki/NaN
(Until I read this, I was not aware that IEEE now recommends that
the quiet-vs-signal bit be 1-for-quiet 0-for-signal. I prefer the
other way around since you can then set memory to all-1-bits if it
contains floating point numbers, and get exceptions if you refer
to a value before seting it.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: gmail (figure it out) http://web.torek.net/torek/index.html
Back to comp.lang.python | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Re: float("nan") in set or as key Carl Banks <pavlovevidence@gmail.com> - 2011-06-03 13:27 -0700
Re: float("nan") in set or as key Chris Angelico <rosuav@gmail.com> - 2011-06-04 06:35 +1000
Re: float("nan") in set or as key Chris Torek <nospam@torek.net> - 2011-06-05 22:54 +0000
Re: float("nan") in set or as key Chris Angelico <rosuav@gmail.com> - 2011-06-06 09:13 +1000
Re: float("nan") in set or as key Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-06-06 01:21 +0000
Re: float("nan") in set or as key Chris Torek <nospam@torek.net> - 2011-06-06 01:56 +0000
Re: float("nan") in set or as key Chris Angelico <rosuav@gmail.com> - 2011-06-06 14:11 +1000
Re: float("nan") in set or as key Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-06-06 04:59 +0000
Re: float("nan") in set or as key Chris Angelico <rosuav@gmail.com> - 2011-06-06 15:10 +1000
Re: float("nan") in set or as key Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-06-04 04:54 +0000
Re: float("nan") in set or as key Ethan Furman <ethan@stoneleaf.us> - 2011-06-03 23:04 -0700
Re: float("nan") in set or as key Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-06-04 09:35 +0000
Re: float("nan") in set or as key Ben Finney <ben+python@benfinney.id.au> - 2011-06-04 20:20 +1000
Re: float("nan") in set or as key Ethan Furman <ethan@stoneleaf.us> - 2011-06-04 14:28 -0700
Re: float("nan") in set or as key Robert Kern <robert.kern@gmail.com> - 2011-06-04 16:49 -0500
Re: float("nan") in set or as key Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-06-05 02:03 +0000
Re: float("nan") in set or as key Robert Kern <robert.kern@gmail.com> - 2011-06-05 14:44 -0500
csiph-web