3
from decimal import *
Pi=Decimal(3.141592653589793238462643383279502884197169399373)
print(Pi)

Actual output:

3.141592653589793115997963468544185161590576171875

Output should be:

3.141592653589793238462643383279502884197169399373

Why does the value change?

CrazyChucky
  • 3,263
  • 4
  • 11
  • 25
abc bcd
  • 131
  • 1
  • 10

2 Answers2

5

You're passing in a floating-point number to the Decimal constructor, and floating-point numbers are inherently imprecise (see also the Python manual).

To pass in a precise number to the Decimal constructor, pass it in as a string.

>>> from decimal import Decimal

# bad
>>> Decimal(3.141592653589793238462643383279502884197169399373)
Decimal('3.141592653589793115997963468544185161590576171875')

# good
>>> Decimal('3.141592653589793238462643383279502884197169399373')
Decimal('3.141592653589793238462643383279502884197169399373')

If you have a floating-point variable, you can cast it to a string first, then to a Decimal to avoid some floating-point imprecision:

>>> a = 0.1 + 0.2
0.30000000000000004
>>> Decimal(a)
Decimal('0.3000000000000000444089209850062616169452667236328125')
>>> Decimal(str(a))
Decimal('0.30000000000000004')
>>>

If you need full precision, just work with Decimals all the way:

>>> Decimal("0.1") + Decimal("0.2")
Decimal('0.3')
AKX
  • 152,115
  • 15
  • 115
  • 172
  • I used this on my calculation but got this error `Pi=Decimal("Pi")+(Decimal("sign")*(Decimal("4")/(Decimal("k")* (Decimal("k")+Decimal("1"))*(Decimal("k")+Decimal("2"))))) decimal.InvalidOperation: []` – abc bcd Mar 29 '22 at 11:49
  • 1
    `Decimal("k")` and `Decimal("sign")` doesn't make sense. If you already have data in floating-point variables called `k` and `sign`, do `Decimal(str(k))` and `Decimal(str(sign))`; the `str()` invocation ensures you're triggering Python's floating point stringification, which turns some overly precise floats into a better form. – AKX Mar 29 '22 at 11:51
  • @abcbcd That's an entirely different question, but look into `pickle` or `json` for storing and loading arbitrary data instead of trying to modify Python files programmatically. – AKX Mar 29 '22 at 12:13
  • i know but i cant make another question for 90 minutes but thank you – abc bcd Mar 29 '22 at 12:14
1

You should pass a string to Decimal(), not a float, floats are imprecise to begin with. Also, note the following from the Python docs

Unlike hardware based binary floating point, the decimal module has a user alterable precision (defaulting to 28 places) which can be as large as needed for a given problem

from decimal import *
getcontext().prec = 100 #precision

pi = Decimal("3.141592653589793238462643383279502884197169399373")
print(pi)    #3.141592653589793238462643383279502884197169399373
alec_djinn
  • 10,104
  • 8
  • 46
  • 71