Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Float random(?!) precision quirk [duplicate]

Tags:

python

I have just started learning python and I have stumbled across a particularity

python version:

Python 2.7.2 (default, Jul 20 2011, 02:32:18) [GCC 4.2.1 (LLVM, Emscripten 1.5, Empythoned)] on linux2

on:http://repl.it/languages/Python

Working with the interpreter assigning:

    pi = 3.141 // 3 places decimal precision
    #typing pi  & pressing return puts 3.141
   type(pi)
=> <type 'float'>
    pi = 3.1415
   type(pi)
=> <type 'float'>
    #pi puts 3.1415000000000002

Ok floating point precision is notorious for being unprecise; but why do only the 4 point precision get that "tail"?

Also:

 pi2 = 3.1415100000000002
 pi == pi2 # pi was assigned 3.1415
 => True
 print(pi2)
 3.14151 # Where's my precision? 
like image 757
raam86 Avatar asked Oct 04 '22 12:10

raam86


1 Answers

Integers and floats are given a certain number of bits. For integers, each bit corresponds to a power of two. The first digit is 20, then 21, 22, and so on. So to store the integer 5 we have 20 + 22 = 1 + 4.

For floating point numbers, we store them in two parts. The exponent, and the decimal. If we have an decimal of .75 and a exponent of 2, we do .75 * 102 = 7.5. The decimal is stored as negative powers of 2. So we have 2-1, 2-2. 2-3. etc. These equate to .5, .25, .125, etc.

Some numbers are impossible to store, because they literally require infinite bits to represent, like 0.1, and others like 3.1415 require more bits than the CPU provides for floating-point numbers (24 is standard for 32bit floats, but algorithms vary).

The correct way to compare floats is to have a variance defined, and use something along these lines.

variance = .0001
floatsEqual = lambda f1, f2: f1 - variance <= f2 and f1 + variance >= f2

if (floatsEqual(3.1415, 3.1415 + 1 - 1)):
    pass

In Python, the decimal library is also useful.

like image 181
Brigand Avatar answered Oct 07 '22 20:10

Brigand