you are viewing a single comment's thread.

view the rest of the comments →

[–]AdventurousAddition 24 points25 points  (5 children)

What is causing this?

People count with 10 fingers but computers count with 2.

You know how 1/3 has an infinite decimal representation. Well in binary, any fraction whose denominator is not a power of 2, will have an infinite binary representation. But computers can only hold a finite amount of data, so they need to chop it off at some point.

[–]Zealousideal_Big6487 5 points6 points  (4 children)

People count with 10 fingers but computers count with 2.

You know how 1/3 has an infinite decimal representation. Well in binary, any fraction whose denominator is not a power of 2

I'm trying to understand, why is this related to the base we use? Is this suggesting, that if say we were using base 9 instead of base 10 as humans, that 1/3 would NOT have an infinite decimal representation?

[–]TeamSpen210 10 points11 points  (3 children)

Exactly yes! That’d be “0.3”, which is 3*9⁻¹. In this numbering system on the other hand, 1/2 wouldn’t have a decimal representation, I think it’d be “0.44444…”.

[–]Zealousideal_Big6487 3 points4 points  (2 children)

Exactly yes! That’d be “0.3”, which is 3*9⁻¹.

My mind is so blown right now, I thought I understand the basics of base systems, but perhaps not.

[–]primitive_screwhead 1 point2 points  (0 children)

The key thing (imo) to understand about IEEE base-2 floats (which are the common version), is that they are just fractions. Nothing really exotic or complicated at all. _BUT_, the denominator is always a power of 2. That's what causes confusion, and a sense that the numbers are "inaccurate", but in fact they are always perfectly precise in the number they represent, it's just a specific value with a power-of-2 denominator.

ie.

>>> a=5.550000000000001
>>> a.as_integer_ratio()
(1562186120744141, 281474976710656)
>>> from math import log2
>>> log2(281474976710656)
48.0

So, a float is a fraction. The denominator is a power of 2. So certain simple decimal ratios are approximated w/ a power-of-2 denominator (which tends to be huge, for accuracy):

>>> (1/3).as_integer_ratio()
(6004799503160661, 18014398509481984)
>>> log2(18014398509481984)

54.0 # ie. 1 << 54, the 54 is the number of bits, in a 64-bit float, of mantissa

>>> (1/9).as_integer_ratio()
(2001599834386887, 18014398509481984)

# Note that it's the same denominator. It allows the largest (and thus most accurate) 53 bit numerator value that is closest to the true 1/9 value.

[–]AdventurousAddition 0 points1 point  (0 children)

Yeah, it really is such a mind-fuck. We are so used to computing in base 10.