Someone pointed out that this isn't correct, and then deleted their comment. (?)
I now think the behiviour I ascribed to print, is actually what repr does. I'm not sure about print, but I guess it is just rounding to a certain number of places.
>>> from decimal import Decimal
>>> Decimal(0.1+0.2)
Decimal('0.3000000000000000444089209850062616169452667236328125')
>>> Decimal(0.3)
Decimal('0.299999999999999988897769753748434595763683319091796875')
>>> Decimal(0.300000000000000000000000000001)
Decimal('0.299999999999999988897769753748434595763683319091796875')
>>> print 0.300000000000000000000000000001
0.3
>>> repr(0.300000000000000000000000000001)
'0.3'
>>> D(0.30000000000000004)
Decimal('0.3000000000000000444089209850062616169452667236328125')
>>> repr(0.299999999999999988897769753748434595763683319091796875)
'0.3'
>>> repr(0.30000000000000004)
'0.30000000000000004'
>>> print 0.30000000000000004
0.3you are using Decimal "wrong". If you want it to handle exact values, you need to pass a string with the decimal interpretation
Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from decimal import Decimal
>>> Decimal('0.1') + Decimal('0.2') - Decimal('0.3')
Decimal('0.0')
>>> Decimal(0.1) + Decimal(0.2) - Decimal(0.3)
Decimal('2.775557561565156540423631668E-17')
>>> Decimal(0.1) == Decimal('0.1')
FalseIn this case, that was deliberate. I was using it to show the exact decimal value of the floating point approximations to decimal numbers, not to do decimal arithmetic.
There's some discussion here: https://docs.python.org/3.1/tutorial/floatingpoint.html. Basically: eval(repr(x)) == x is guaranteed, and some attempt is made to give the shortest such string representation for Python 3.1+ (and 2.7?), but it's not guaranteed on all platforms.
Re:0.30000000000000004
by indosauros on Friday November 13, 2015 @08:06AM
(#10559588)
It also matters whether you're using Python 2 or 3. This is one of the things they changed in 3:
>>> print(0.1 + 0.2)
0.30000000000000004I believe this is relevant:
https://bugs.python.org/issue1580
I'm not sure, but I think it's not really about cutting off the digits (although that's the effect it has). At least with python, I think what happens is:
* repr gives you the decimal number with the exact value of the floating-point number, i.e. 0.30000000000000004
* print gives you the least-precise decimal number whose closest floating-point representation is equal to the floating-point number
That is, there are (infinitely) many decimal numbers such that the closest floating-point representation has the value 0.30000000000000004. One of these decimal numbers is 0.3, and of all such decimal numbers, this has the fewest digits. So that's the one that gets printed.