0

Using the following code:

import numpy as np
k = .2
A = np.arange(.01, k, .01, dtype=np.float64)

# values
print(A)
print([A[i] for i in range(len(A))])

# comparison
print(A == [A[i] for i in range(len(A))])

# check for value
print(.06 in A)

The corresponding output is:

[0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1  0.11 0.12 0.13 0.14
 0.15 0.16 0.17 0.18 0.19]
[0.01, 0.02, 0.03, 0.04, 0.05, 0.060000000000000005, 0.06999999999999999, 0.08, 0.09, 0.09999999999999999, 0.11, 0.12, 0.13, 0.14, 0.15000000000000002, 0.16, 0.17, 0.18000000000000002, 0.19]
[ True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True]
False

What sort of magic is happening here ? How am I supposed to iterate over the array keeping precision ?

EDIT: as precised in Is floating point math broken ? this lost of precision is a known issue, language agnostic. I would know what is the python way to handle this ? Using an epsilon seems to be a little hacky for me

Loheek
  • 1,865
  • 17
  • 28
  • 4
    Possible duplicate of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – pault Mar 28 '18 at 14:06
  • One option is to check that the absolute value of the difference is less than some epsilon: `print([abs(A[i] - 0.6) < 1e-10 for i in range(len(A))])`. There are also infinite precision libraries available. It all depends on what you're trying to do. – pault Mar 28 '18 at 14:08
  • @pault I understand my first question is duplicate but I would be interested in a response to the second one, more python specific – Loheek Mar 28 '18 at 14:10
  • 1
    What is the desired output? To check the existence of the value in the array, you could do something like `print(any(abs(A[i]-0.06) < 1e-10 for i in range(len(A))))` – pault Mar 28 '18 at 14:14
  • Thank you, I will use this work around. Is there a more python way to handle this ? – Loheek Mar 28 '18 at 14:17
  • Try the [`decimal`](https://docs.python.org/3/library/decimal.html) library. – pault Mar 28 '18 at 14:18
  • Eventually you will either 1. Write the precision check inline 2. use a library that will do it for you. There is no more pythonic way than just do it and get over with. – mr_mo Mar 28 '18 at 14:20

1 Answers1

0

If you just use a multi-line for loop for this the 'problem' goes away. It seems to be an 'issue' when using the generator.

for i in range (len(A)):
    print(A[i])

gives

0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.1
0.11
0.12
0.13
0.14
0.15
0.16
0.18
0.19
Jay
  • 75
  • 1
  • 9
  • See **help(np.arange)**. In fact, to be sure to obtain an exact representation of the solution, you need to use **np.linspace()** instead of **np.arange()** as _np.arange()_ is more accurate with **integer** _step_ – eapetcho Mar 29 '18 at 17:24