[Python-ideas] Python Numbers as Human Concept Decimal System

Steven D'Aprano steve at pearwood.info
Sun Mar 9 08:32:29 CET 2014


On Sat, Mar 08, 2014 at 01:59:32PM -0800, Ethan Furman wrote:

> Python 3.4.0b3+ (default:aab7258a31d3, Feb  7 2014, 10:48:46)
> [GCC 4.7.3] on linux
> Type "help", "copyright", "credits" or "license" for more information.
> --> from decimal import Decimal as D
> --> 9017.0109812864350067128347806
> 9017.010981286436
> --> D(9017.0109812864350067128347806)
> Decimal('9017.01098128643570817075669765472412109375')
> 
> In case my question isn't obvious, the direct float got me 16 digits, while 
> the Decimal float got me 42 digits.  Why is the Decimal more "accurate" 
> that the float it came from?

That's an interesting question. It does appear to be a lot more digits 
than needed. Here's that float exactly, in hex:

py> 9017.010981286436.hex()
'0x1.19c8167d5b50ep+13'

Let's convert it to decimal:


py> digits = list('19c8167d5b50e')
py> for i, c in enumerate(digits):
...     digits[i] = '0123456789abcdef'.index(c)
...
py> d = Decimal(0)
py> for n in digits[::-1]:
...     d += n
...     d /= 16
...
py> d += 1
py> d *= 2**13
py> d
Decimal('9017.010981286435708170756694')

Note that this round-trips back to float correctly:

py> assert float(d) == 9017.010981286436
py>


So I must admit, I'm not sure where the extra digits come from:

Decimal('9017.01098128643570817075669765472412109375')
Decimal('9017.010981286435708170756694')

but perhaps my calculation was rather naive.



-- 
Steven


More information about the Python-ideas mailing list