Floating point
Floating point numbers allow both large and small numbers to be represented in a small amount of memory by keeping a binary fraction and an exponent. This makes them very useful, however they are not without some interesting problems.
Floating point issues
At first this seems nonsensical:
$ tmp = 0.1 + 0.1 + 0.1 == 0.3 "[tmp]"
FalseIn decimal it seems obvious that the result should be
True
.
Floats work with binary fractions though, and there isn't a precise
representation of 0.1, just a in decimal there's no precise representation
of one third.
These approximations tend to be hidden when printing floating point
numbers as rather than printing all the digits, values are rounded.
So while two numbers may look the same when printed their values are
different.
Another surprise awaits with this code:
$ tmp = 2.0 ** 53 "[tmp:,f]" $ tmp += 1 "[tmp:,f]"
9,007,119,254,740,992.000000Surely the second number should be one bigger than the first? The problem here is that with numbers this big the next value is actually 2 higher, so no matter how many times 1 is added the result doesn't change.
9,007,119,254,740,992.000000
See Floating point issues for more information.
Special numbers
In addition to the numbers you might expect there are some special values:
- +0, -0
- There are two zeros, a positive one and a negative one.
- inf, -inf
- There are two infinity values, a positive and a negative one.
- nan
- This stands for "not a number" and can result from nonsensical operations like trying to multiply infinity by zero.
Float literals
A floating point number has either a decimal point .
or
an exponent e
or E
, or both. The exponent
may have a sign +
or -
.
Underscores _
may be used to group digits.
See
Python: floating point literals
Comparing floats
In general, due to the issues above, avoid comparing floats for
equality or inequality using ==
and !=
.
Two floats that ought to be the same, and print the same, may have
differences in their actual values.
If you absolutely must compare floats consider using
math.isClose()