简体   繁体   中英

Python “decimal” package gives wrong results

I tried to compute the following by setting getcontext().prec = 800 .

>>> from decimal import *
>>> getcontext().prec = 800
>>> Decimal(22.0) / Decimal ( 10.0) - Decimal ( 0.2 )
Decimal('1.999999999999999988897769753748434595763683319091796875')
>>> 

But the expected result is 2 . Where am I doing wrong?

The prec attribute defines how many numbers after the decimal point will round your number. For example, if you expect 2.00 , its value should be 3 . Or if you want to round the number so that it has no decimal places you can use 1 as a parameter.

from decimal import *

getcontext().prec = 1
print(Decimal(22.0) / Decimal ( 10.0) - Decimal ( 0.2 ))
>> 2

When you construct a Decimal from a floating-point number, you get the exact value of the floating-point number, which may not precisely match the decimal value because that's how floating-point numbers work.

If you want to do precise decimal arithmetic, construct your Decimal objects from strings instead of floating-point numbers:

>>> Decimal('22.0') / Decimal('10.0') - Decimal('0.2')
Decimal('2.0')

It seems that you have to give numbers as a string to prevent them from being evaluated as floating point.

from decimal import *
getcontext().prec = 800
print(Decimal(0.2))
print(Decimal('0.2'))
print(Decimal('22.0') / Decimal ('10.0') - Decimal ('0.2' ))

which gives

0.200000000000000011102230246251565404236316680908203125
0.2
2.0

Pass strings to the Decimal constructor instead of floats: Decimal('0.2') gives the result you expect, Decimal(0.2) doesn't.

This is because:

If value is a float, the binary floating point value is losslessly converted to its exact decimal equivalent. This conversion can often require 53 or more digits of precision. For example, Decimal(float('1.1')) converts to Decimal('1.100000000000000088817841970012523233890533447265625').

https://docs.python.org/3/library/decimal.html#decimal.Decimal

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM