How are Inf and NaN implemented?

2020-02-11 01:57发布

As mathematical concepts, I am well aware of what inf and nan actually are. But what I am really interested in is how they are implemented in programming languages.

In python, I can use inf and nan in arithmetic and conditional expressions, like this:

>>> nan = float('nan')
>>> inf = float('inf')
>>> 1 + inf
inf
>>> inf + inf
inf
>>> inf - inf
nan

This would lead me to believe that python internally has a special reserved bit sequence for these two mathematical quantities, and no other number can assume these positions. Is my assumption correct? Can you please enlighten me in this regard?

If my assumption is correct, then this can be explained easily:

>>> inf == inf
True

However, this is not:

>>> nan == nan
False

Obviously, in mathematics, this is the right answer. But how does python know that it should spit out False in this instance?

Furthermore, how does python's implementation differ from that of java or c++?

2条回答
放我归山
2楼-- · 2020-02-11 02:10

Typically, the floating point arithmetic is implemented directly by hardware. There are indeed special bit patterns for infinity and NaN, which are recognized by the hardware floating-point unit.

IEEE 64-bit floating-point numbers, the kind used in CPython on typical systems, have 1 bit for the sign, 11 bits for the exponent, and 52 bits for the mantissa. See https://en.wikipedia.org/wiki/Double-precision_floating-point_format

If the exponent contains 0b11111111111 (all ones), then the number is either inf or nan, depending on what is stored in the mantissa. Python does not need to do anything special to handle these cases. You will get the same results whether you compare the numbers in Python, C, Java, or assembly language.

查看更多
看我几分像从前
3楼-- · 2020-02-11 02:26

Those are not python-specific behavior, it's rather the floating-point standard Python use (and possibly all common languages?).

nan and inf are special value of the IEEE_754 floating point standard. They have internal representations (the bit sequence you mention) of course, but their behavior is not usual. The behavior is not usual wrt other floats values, but it is well defined by IEEE_754. Implementation is handled at instruction level. (The processor handle this in its floating-point unit circuitry)

One specified and not trivial behavior, NaN != everything, including itself.

Knowing that, you can write something like:

def isNaN(f): return f != f
查看更多
登录 后发表回答