Could someone specifically explain why the last digit is 5 instead of 2 or 4? Knowing a float must have an inaccuracy in the binary world, I can't get exactly how the result of the case above has been made in detail.
It's because it's the closest a (64bit) float
can be to the "true value" of 10/3
.
I use cython here (to wrap math.h nexttoward
function) because I don't know any builtin function for this:
%load_ext cython
%%cython
cdef extern from "<math.h>" nogil:
# A function that get's the next representable float for the
# first argument in direction to the second argument.
double nexttoward(double, long double)
def next_float_toward(double i, long double j):
return nexttoward(i, j)
(or as pointed out by @DSM you could also use numpy.nextafter
)
When I display the values for 10/3
and the previous and next representable float for this value I get:
>>> '{:.50}'.format(10/3)
3.3333333333333334813630699500208720564842224121094
>>> '{:.50}'.format(next_float_toward(10/3., 0))
3.3333333333333330372738600999582558870315551757812
>>> '{:.50}'.format(next_float_toward(10/3., 10))
3.3333333333333339254522798000834882259368896484375
So each other representable floating point value is "further" away.
Because the largest representable value smaller than ...335 is ...330 (specifically, it's smaller by 2**-51
, or one Unit in the Last Place). ...333 is closer to ...335 than it is to ...330, so this is the best possible rounding.
There are a number of ways to confirm this; MSeifert shows one thing you can do directly with <math.h>
from C or Cython. You can also use this visualization tool (found by Googling "floating point representation" and picking one of the top results) to play with the binary representation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With