F
F
Fedor2013-11-19 07:59:28
Python
Fedor, 2013-11-19 07:59:28

Python: Why is there an error in the process of summing decimals in the middle of an interval?

Hello, dear habravchane.
The topic is indicated in the title. First grade code. BUT in the process of summation (increasing values ​​by a constant), an error accumulates, which then disappears.

>>> interv = 10
>>> start = -2
>>> stop = 2
>>> mas =[]
>>> step = 0.4
>>> mas.append(start)
>>> for i in range(1, interv):
  mas.append(mas[i-1]+step)


And as a result, strange things are observed
>>> mas
[-2, -1.6, -1.2000000000000002, -0.8000000000000002, -0.40000000000000013, -1.1102230246251565e-16, 0.3999999999999999, 0.7999999999999999, 1.2, 1.6]

Of course, you can use rounding, but this is not always the way out and I would like to understand why this error occurs.

Answer the question

In order to leave comments, you need to log in

5 answer(s)
A
alexmuz, 2013-11-19
@alexmuz

Read: http://habrahabr.ru/post/112953/

S
Sergey Pankov, 2013-11-20
@trapwalker

In fact, the described problem can be illustrated more simply:

>>> 0.5+2.7, 0.4+2.8
(3.2, 3.1999999999999997)

This is the normal situation for floating point numbers. It is connected with the fact that for any number system (binary, decimal, ternary) there are numbers that cannot be written as a finite sequence of n-ary digits. For example, in decimal, the number 1/3 will look like an endless sequence of triples after the decimal point. If we stop, we will get not 1/3 but something smaller. But in the ternary system, this number is wonderfully represented as 0.1. One ninth in the ternary system is equal to 0.01.
The same problem, for example, with the decimal number 0.2 when converted to binary:
2/10==1/5==1/8+1/16+1/128+1/256+1/2048+1/4096+ (...)==0.00110011(0011)[in binary]
As we can see, this is a periodic number and binary digits "0011" are repeated in it after the decimal point endlessly.
The computer representation of floating point numbers involves storing them in a finite number of binary digits. This means that many fractional numbers that are quite normally written in decimal form simply cannot be stored exactly in a computer (if we are talking about floatpoint).
That is why programmers are taught in their first year of college never to compare floating-point numbers for strict equality and inequality. Given the error due to rounding of binary digits, this is simply meaningless and incorrect.
But, instead of comparing for equality, you can compare abs(a-b)<eps, where aandbare floating point numbers, and eps is some negligible value. In fact, I think that even the minimum value of this value can be calculated so that it covers all the troubles with rounding binary digits.

V
Vladimir Shalaev, 2013-11-19
@f222314

In my opinion, there is nothing special here. Normal error for real numbers.

P
PaulOkopny, 2013-11-19
@PaulOkopny

Quite a normal situation for floating point numbers. Want to get rid of - use decimal.

A
Ali Aliyev, 2013-11-19
@ali_aliev

The reason for this strange behavior is the limitation of the hardware that implements the real math. Example:

>>> f = 1/3.0
>>> f
0.3333333333333333
>>> '%4.2f' % f
'0.33'
>>>

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question