numpy - Python (strangely) rounding values -


this question has answer here:

this question more curiosity.

i'm creating following array:

a = zeros((2,2)) in range(2):     a[i,i] = 0.6     a[(i+1)%2,i] = 0.4 print  >>>    [[ 0.6  0.4]    [ 0.4  0.6]] 

then, printing it:

for i,c in enumerate(a):     j,d in enumerate(c):         print j, d 

but, if remove j, got:

>>> 0 0.6 1 0.4 0 0.4 1 0.6 

but if remove j for, got:

(0, 0.59999999999999998) (1, 0.40000000000000002) (0, 0.40000000000000002) (1, 0.59999999999999998) 

it because way i'm creating matrix, using 0.6? how represent internally real values?

there few different things going on here.

first, python has 2 mechanisms turning object string, called repr , str. repr supposed give 'faithful' output (ideally) make easy recreate object, while str aims more human-readable output. floats in python versions , including python 3.1, repr gives enough digits determine value of float (so evaluating returned string gives float), while str rounds 12 decimal places; has effect of hiding inaccuracies, means 2 distinct floats close can end same str value - can't happen repr. when print object, str of object. in contrast, when evaluate expression @ interpreter prompt, repr.

for example (here using python 2.7):

>>> x = 1.0 / 7.0 >>> str(x) '0.142857142857' >>> repr(x) '0.14285714285714285' >>> print x  # print uses 'str' 0.142857142857 >>> x  # interpreter read-eval-print loop uses 'repr' 0.14285714285714285 

but also, little bit confusingly point of view, get:

>>> x = 0.4 >>> str(x) '0.4' >>> repr(x) '0.4' 

that doesn't seem tie in seeing above, we'll come below.

the second thing bear in mind in first example, you're printing 2 separate items, while in second example (with j removed), you're printing single item: tuple of length 2. surprisingly, when converting tuple printing str, python nevertheless uses repr compute string representation of elements of tuple:

>>> x = 1.0 / 7.0 >>> print x, x  # print x twice;  uses str(x) 0.142857142857 0.142857142857 >>> print(x, x)  # print single tuple; uses repr(x) (0.14285714285714285, 0.14285714285714285) 

that explains why you're seeing different results in 2 cases, though underlying floats same.

but there's 1 last piece puzzle. in python >= 2.7, saw above particular float 0.4, str , repr of float same. 0.40000000000000002 come from? well, don't have python floats here: because you're getting these values numpy array, they're of type numpy.float64:

>>> numpy import zeros >>> = zeros((2, 2)) >>> a[:] = [[0.6, 0.4], [0.4, 0.6]] >>> array([[ 0.6,  0.4],        [ 0.4,  0.6]]) >>> type(a[0, 0]) <type 'numpy.float64'> 

that type still stores double-precision float, python's float, it's got goodies make interact nicely rest of numpy. , turns out numpy uses different algorithm computing repr of numpy.float64 python uses computing repr of float. python (in versions >= 2.7) aims give shortest string still gives accurate representation of float, while numpy outputs string based on rounding underlying value 17 significant digits. going 0.4 example above, here's numpy does:

>>> numpy import float64 >>> x = float64(1.0 / 7.0) >>> str(x) '0.142857142857' >>> repr(x) '0.14285714285714285' >>> x = float64(0.4) >>> str(x) '0.4' >>> repr(x) '0.40000000000000002' 

so these 3 things should explain results you're seeing. rest assured cosmetic: underlying floating-point value not being changed in way; it's being displayed differently 4 different possible combinations of str , repr 2 types: float , numpy.float64.

the python tutorial give more details of how python floats stored , displayed, of potential pitfalls. answers this question have more information on difference between str , repr.


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

thorough guide for profiling racket code -