1

I'm trying to create a script that counts to 3 (step size 0.1) using while, and I'm trying to make it not display .0 for numbers without decimal number (1.0 should be displayed as 1, 2.0 should be 2...) What I tried to do is convert the float to int and then check if they equal. the problem is that it works only with the first number (0) but it doesn't work when it gets to 1.0 and 2.0..

this is my code:

i = 0
while i < 3.1:
    if int(i) == i:
        print int(i)
    else:
        print i
    i = i + 0.1

that's the output I get:

0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
1.9
2.0
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
3.0

the output I should get:

0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
1.9
2
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
3

thank you for your time.

morha13
  • 1,847
  • 3
  • 21
  • 42
  • 2
    Floating point numbers are not exact. There are many good tutorials on this. For example, see [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html). – John1024 Sep 02 '16 at 21:38
  • 2
    Floating point arithmetic is approximate. When you add `.1` 10 times, you don't get `1.0`. – Barmar Sep 02 '16 at 21:38
  • 1
    Possible duplicate of [Is floating point math broken?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Barmar Sep 02 '16 at 21:39
  • @John1024 and Barmar thank you! – morha13 Sep 02 '16 at 21:42

2 Answers2

3

Due to lack of precision in floating point numbers, they will not have an exact integral representation. Therefore, you want to make sure the difference is smaller than some small epsilon.

epsilon = 1e-10
i = 0
while i < 3.1:
    if abs(round(i) - i) < epsilon:
        print round(i)
    else:
        print i
    i = i + 0.1
aganders3
  • 5,838
  • 26
  • 30
  • Thank you! Can't accept the answer yet.. what does epsilon means? What is that 1e-10 – morha13 Sep 02 '16 at 21:40
  • 2
    Python 3 has an `isclose` function that solves this problem. It just means that if the difference is really small, it must be an "integer" – cwahls Sep 02 '16 at 21:41
  • `epsilon` is just kind of a math-y term for a very small number. `1e-10` is equal to `1 * 10 ^ -10` which is `0.0000000001` – aganders3 Sep 02 '16 at 21:43
  • @aganders3 ok thank you! and what happens if I want to count to 10 instead of 3? When I tried using epsilon it worked just untill 4.. – morha13 Sep 02 '16 at 22:06
  • @morha13 thanks, this causes issues because sometimes the floating point representation is smaller than the integer by a bit, and `int()` will simply truncate the decimals. I updated my answer to use `round` instead. – aganders3 Sep 02 '16 at 22:39
2

You can remove trailing zeros with '{0:g}'.format(1.00).

i = 0
while i < 3.1:
    if int(i) == i:
        print int(i)
    else:
        print '{0:g}'.format(i)
    i = i + 0.1

See: https://docs.python.org/3/library/string.html#format-specification-mini-language

Update: Too lazy while copy/pasting. Thanks @aganders3

i = 0
while i < 3.1:
    print '{0:g}'.format(i)
    i = i + 0.1
adabsurdum
  • 91
  • 8