可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I need a class holding 1000 decimal digits to calculate something like pi number in a series. Taking time is not important. How can I define __add__
& ... functions to do this?
For example I need a value can hold this number:
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113
:))
This number using decimal.Decimal
shows like this:
from decimal import Decimal as dc
>>> x=dc(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113)
>>> x
Decimal('3.141592653589793115997963468544185161590576171875')
But I need a new class holding all DIGITS and I can use adding, dividing and ... functions in it like 2+1 and pi number is an example of that and exactly I don't need to calculate pi number I wanted to calculate extra large decimal numbers!
回答1:
You have to set a context with 1000 decimal digits:
context = decimal.Context(prec=1000)
decimal.setcontext(context)
From now on computations will use 1000 digits precision.
Example:
>>> decimal.setcontext(decimal.Context(prec=1000))
>>> pi = decimal.Decimal('3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113')
>>> pi
Decimal('3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113')
>>> pi + 2
Decimal('5.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113')
Note that:
- You have to use strings to initialize the
Decimal
because if you use a float
the interpreter will have to truncate it first. (also I believe only the most recent versions of decimal
accept a float
argument. In older versions you had to use Decimal.from_float
instead).
- The decimal digits are preserved during calculations.
You can also use the context locally via the localcontext
contextmanager:
context = decimal.Context(prec=1000)
with decimal.localcontext(context):
# here decimal uses 1000 digits for computations
pass
# here the default context is restored.
回答2:
You made the mistake of initialising the Decimal
object with a double
which can't represent your big number.
So instead of saying:
x=dc(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113)
...which has exactly the same effect as:
x=dc(3.1415926535897932384626433832795)
...initialise from a string:
x=dc('3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113')
and you'll get the expected result with full precision.
回答3:
My try. Might NOT be very good.
class pi:
def __init__(self):
self.pi_digits = ['1', '4', '1', '5', '9', '2', '6'] # pi = 3.1415926
def __repr__(self):
return '3.'+''.join(self.pi_digits)
def add(self, digit):
digit = str(digit)
if digit.isdigit():
self.pi_digits.append(digit)
else:
raise TypeError
my_pi = pi()
my_pi.add(3)
my_pi.add(5)
print (my_pi)
Output
3.141592635
PS - This is just to give you a rough idea of how you might go about doing things.
回答4:
This function will give you string of value based on numerator (numer) and denominator (deno) and precision which can be used for any fractional number not just for pi. For pi, you can just use 22/7 and any precision you want.
def pi_accur(numer,deno,precision):
pi_holder=[]
while (precision>=1):
pi_holder.append(int(numer/deno))
numer=10*(numer%deno)
precision=precision-1
new_val=str(pi_holder[0])+'.'
for i in pi_holder[1:]:
new_val=new_val+str(i)
return new_val
>>> pi_accur(22,7,9)
'3.14285714'
>>>pi_accur(22,7,15)
'3.14285714285714'