Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is 10/3 equal to 3.3333333333333335 instead of ...332 or ..334?

Tags:

python

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.

like image 387
Jacob Avatar asked Dec 17 '16 02:12

Jacob


2 Answers

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.

like image 141
MSeifert Avatar answered Nov 09 '22 02:11

MSeifert


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.

like image 21
Kevin Avatar answered Nov 09 '22 03:11

Kevin