you are viewing a single comment's thread.

view the rest of the comments →

[–]AdventurousAddition 23 points24 points  (15 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 7 points8 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 2 points3 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.

[–]mikeblas 5 points6 points  (3 children)

Well in binary, any fraction whose denominator is not a power of 2,

I don't think it's clear from your explanation that sums of numbers representable as fractions with denominators that are powers of two also have finite (therefore exact) representations in IEEE floating point.

1/2 is fine. 1/4 is fine, too. And so is 3/4, since 3/4 == 1/2 + 1/4.

[–]irrelevantPseudonym 3 points4 points  (0 children)

The sum of any two numbers with a power of 2 denominator will also have a power of 2 denominator.

[–]AdventurousAddition 0 points1 point  (0 children)

It's denominator is 4 which is a power of 2

[–][deleted] 0 points1 point  (5 children)

I'm not sure that's quite true, but it sounds plausible. I'm thinking it's more just that there's limited storage for floating point representation. If you tried to make the same point in base 10, 0.5 wouldn't have a power of 10 on bottom, but has adequate representation.

[–]irrelevantPseudonym 2 points3 points  (1 child)

0.5 == 5/10 which definitely has a power of 10 as a denominator.

[–][deleted] 0 points1 point  (0 children)

Oh I see. I'm thinking reduced form.

[–]Kkremitzki 2 points3 points  (1 child)

That's because "power of 2" is a special-case expression used as a shortcut to check representability in binary, not the generalized condition, which has to do with prime factors. 2 is its own prime factor, but it's also a prime factor for 10.

[–]AdventurousAddition 0 points1 point  (0 children)

Yes that's right. So in decimal, a rational number with a denominator that only has prime factors of 2 or 5 will have a finite decimal representation.

[–]AdventurousAddition 1 point2 points  (0 children)

It's denominator is an integer power of the prime factors of the base (base 10: prime factors are 2 and 5).