decimal
— Decimal aritmetik med fasta och flytande kommatecken¶
Källkod: Lib/decimal.py
Modulen decimal
ger stöd för snabb, korrekt avrundad decimal aritmetik med flyttal. Den erbjuder flera fördelar jämfört med datatypen float
:
Decimal ”är baserat på en flyttalsmodell som utformades med människor i åtanke och som nödvändigtvis har en överordnad vägledande princip - datorer måste tillhandahålla en aritmetik som fungerar på samma sätt som den aritmetik som människor lär sig i skolan.” – Utdrag ur specifikationen för decimal aritmetik.
Decimaltal kan representeras exakt. Däremot har tal som
1,1
och2,2
inte exakta representationer i binär flyttal. Slutanvändare förväntar sig vanligtvis inte att1,1 + 2,2
ska visas som3,3000000000000003
som det gör med binär flyttal.Exaktheten överförs till aritmetik. I decimal flyttal är
0.1 + 0.1 + 0.1 - 0.3
exakt lika med noll. I binär flyttal blir resultatet5.5511151231257827e-017
. Även om skillnaderna är nära noll förhindrar de tillförlitlig jämlikhetstestning och skillnaderna kan ackumuleras. Av denna anledning föredras decimal i bokföringsapplikationer som har strikta jämlikhetsinvarianter.Decimalmodulen innehåller ett begrepp om signifikanta ställen så att
1,30 + 1,20
är2,50
. Den efterföljande nollan behålls för att indikera signifikans. Detta är den gängse presentationen för monetära tillämpningar. Vid multiplikation används enligt ”skolboken” alla siffror i multiplikanden. Till exempel ger1,3 * 1,2
1,56
medan1,30 * 1,20
ger1,5600
.Till skillnad från maskinvarubaserad binär flyttalsräkning har decimalmodulen en precision som kan ändras av användaren (standard är 28 enheter) och som kan vara så stor som behövs för ett visst problem:
>>> from decimal import * >>> getcontext().prec = 6 >>> Decimal(1) / Decimal(7) Decimal('0.142857') >>> getcontext().prec = 28 >>> Decimal(1) / Decimal(7) Decimal('0.1428571428571428571428571429')
Både binär och decimal flyttal implementeras i enlighet med publicerade standarder. Medan den inbyggda float-typen bara visar en blygsam del av sina möjligheter, visar decimalmodulen alla nödvändiga delar av standarden. När det behövs har programmeraren full kontroll över avrundning och signalhantering. Detta inkluderar ett alternativ för att genomdriva exakt aritmetik genom att använda undantag för att blockera alla inexakta operationer.
Decimalmodulen utformades för att ”utan fördomar stödja både exakt oavrundad decimalaritmetik (ibland kallad fastpunktsaritmetik) och avrundad flyttalsaritmetik” – Utdrag ur specifikationen för decimalaritmetik.
Modulens design är centrerad kring tre koncept: decimaltalet, sammanhanget för aritmetik och signaler.
Ett decimaltal är oföränderligt. Det har ett tecken, koefficientsiffror och en exponent. För att bevara signifikansen trunkeras inte nollorna i koefficientsiffrorna. Decimaltal innehåller också specialvärden som Infinity
, -Infinity
och NaN
. Standarden skiljer också mellan -0
och +0
.
Kontexten för aritmetik är en miljö som anger precision, avrundningsregler, gränser för exponenter, flaggor som anger resultatet av operationer och trap enablers som avgör om signaler ska behandlas som undantag. Avrundningsalternativ inkluderar ROUND_CEILING
, ROUND_DOWN
, ROUND_FLOOR
, ROUND_HALF_DOWN
, ROUND_HALF_EVEN
, ROUND_HALF_UP
, ROUND_UP
och ROUND_05UP
.
Signaler är grupper av exceptionella förhållanden som uppstår under beräkningarnas gång. Beroende på applikationens behov kan signaler ignoreras, betraktas som information eller behandlas som undantag. Signalerna i decimalmodulen är: Clamped
, InvalidOperation
, DivisionByZero
, Inexact
, Rounded
, Subnormal
, Overflow
, Underflow
och FloatOperation
.
För varje signal finns det en flagga och en fällaktiverare. När en signal påträffas sätts dess flagga till ett, och om trap enabler sätts till ett utlöses ett undantag. Flaggor är ”sticky”, så användaren måste återställa dem innan han/hon övervakar en beräkning.
Se även
IBM:s allmänna decimalaritmetiska specifikation, The General Decimal Arithmetic Specification.
Handledning för snabbstart¶
Den vanliga starten för att använda decimaler är att importera modulen, se den aktuella kontexten med getcontext()
och, om nödvändigt, ange nya värden för precision, avrundning eller aktiverade fällor:
>>> from decimal import *
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
capitals=1, clamp=0, flags=[], traps=[Overflow, DivisionByZero,
InvalidOperation])
>>> getcontext().prec = 7 # Set a new precision
Decimalinstanser kan konstrueras från heltal, strängar, flyttal eller tupler. Konstruktion från ett heltal eller en float utför en exakt konvertering av värdet för det heltalet eller floaten. Decimaltal innehåller specialvärden som NaN
som står för ”Not a number”, positiva och negativa Infinity
, och -0
:
>>> getcontext().prec = 28
>>> Decimal(10)
Decimal('10')
>>> Decimal('3.14')
Decimal('3.14')
>>> Decimal(3.14)
Decimal('3.140000000000000124344978758017532527446746826171875')
>>> Decimal((0, (3, 1, 4), -2))
Decimal('3.14')
>>> Decimal(str(2.0 ** 0.5))
Decimal('1.4142135623730951')
>>> Decimal(2) ** Decimal('0.5')
Decimal('1.414213562373095048801688724')
>>> Decimal('NaN')
Decimal('NaN')
>>> Decimal('-Infinity')
Decimal('-Infinity')
Om signalen FloatOperation
är fångad, kommer oavsiktlig blandning av decimaler och flyttal i konstruktörer eller orderjämförelser att ge upphov till ett undantag:
>>> c = getcontext()
>>> c.traps[FloatOperation] = True
>>> Decimal(3.14)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
>>> Decimal('3.5') < 3.7
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
>>> Decimal('3.5') == 3.5
True
Tillagd i version 3.3.
Betydelsen av en ny decimal bestäms enbart av antalet inmatade siffror. Kontextens precision och avrundning spelar bara in under aritmetiska operationer.
>>> getcontext().prec = 6
>>> Decimal('3.0')
Decimal('3.0')
>>> Decimal('3.1415926535')
Decimal('3.1415926535')
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85987')
>>> getcontext().rounding = ROUND_UP
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85988')
Om de interna gränserna för C-versionen överskrids, ger konstruktionen av en decimal InvalidOperation
:
>>> Decimal("1e9999999999999999999")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
Ändrad i version 3.3.
Decimaler samverkar bra med mycket av resten av Python. Här är en liten flygande cirkus med decimala flyttal:
>>> data = list(map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))
>>> max(data)
Decimal('9.25')
>>> min(data)
Decimal('0.03')
>>> sorted(data)
[Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('1.87'),
Decimal('2.35'), Decimal('3.45'), Decimal('9.25')]
>>> sum(data)
Decimal('19.29')
>>> a,b,c = data[:3]
>>> str(a)
'1.34'
>>> float(a)
1.34
>>> round(a, 1)
Decimal('1.3')
>>> int(a)
1
>>> a * 5
Decimal('6.70')
>>> a * b
Decimal('2.5058')
>>> c % a
Decimal('0.77')
Och vissa matematiska funktioner är också tillgängliga för Decimal:
>>> getcontext().prec = 28
>>> Decimal(2).sqrt()
Decimal('1.414213562373095048801688724')
>>> Decimal(1).exp()
Decimal('2.718281828459045235360287471')
>>> Decimal('10').ln()
Decimal('2.302585092994045684017991455')
>>> Decimal('10').log10()
Decimal('1')
Metoden quantize()
avrundar ett tal till en fast exponent. Denna metod är användbar för monetära applikationer som ofta avrundar resultat till ett fast antal enheter:
>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
Decimal('7.32')
>>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)
Decimal('8')
Som visas ovan får funktionen getcontext()
tillgång till det aktuella sammanhanget och gör det möjligt att ändra inställningarna. Detta tillvägagångssätt uppfyller behoven i de flesta applikationer.
För mer avancerat arbete kan det vara användbart att skapa alternativa kontexter med hjälp av Context()-konstruktören. För att göra en alternativ kontext aktiv, använd funktionen setcontext()
.
I enlighet med standarden tillhandahåller modulen decimal
två standardkontexter som är färdiga att använda, BasicContext
och ExtendedContext
. Den förstnämnda är speciellt användbar för felsökning eftersom många av fällorna är aktiverade:
>>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)
>>> setcontext(myothercontext)
>>> Decimal(1) / Decimal(7)
Decimal('0.142857142857142857142857142857142857142857142857142857142857')
>>> ExtendedContext
Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
capitals=1, clamp=0, flags=[], traps=[])
>>> setcontext(ExtendedContext)
>>> Decimal(1) / Decimal(7)
Decimal('0.142857143')
>>> Decimal(42) / Decimal(0)
Decimal('Infinity')
>>> setcontext(BasicContext)
>>> Decimal(42) / Decimal(0)
Traceback (most recent call last):
File "<pyshell#143>", line 1, in -toplevel-
Decimal(42) / Decimal(0)
DivisionByZero: x / 0
Kontexter har också signalflaggor för övervakning av exceptionella förhållanden som uppstår under beräkningar. Flaggorna förblir inställda tills de uttryckligen rensas, så det är bäst att rensa flaggorna före varje uppsättning av övervakade beräkningar genom att använda metoden clear_flags()
.
>>> setcontext(ExtendedContext)
>>> getcontext().clear_flags()
>>> Decimal(355) / Decimal(113)
Decimal('3.14159292')
>>> getcontext()
Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[])
Posten flags visar att den rationella approximationen av pi avrundades (siffror utanför kontextprecisionen kastades bort) och att resultatet är inexakt (några av de bortkastade siffrorna var andra än noll).
Enskilda fällor ställs in med hjälp av ordlistan i attributet traps
i en kontext:
>>> setcontext(ExtendedContext)
>>> Decimal(1) / Decimal(0)
Decimal('Infinity')
>>> getcontext().traps[DivisionByZero] = 1
>>> Decimal(1) / Decimal(0)
Traceback (most recent call last):
File "<pyshell#112>", line 1, in -toplevel-
Decimal(1) / Decimal(0)
DivisionByZero: x / 0
De flesta program justerar den aktuella kontexten endast en gång, i början av programmet. Och i många applikationer konverteras data till Decimal
med en enda cast inuti en loop. När kontexten är inställd och decimaler skapade, manipulerar huvuddelen av programmet data på samma sätt som med andra numeriska Python-typer.
Decimala objekt¶
- class decimal.Decimal(value='0', context=None)¶
Konstruera ett nytt
Decimal
-objekt baserat på värde.value kan vara ett heltal, en sträng, en tupel,
float
eller ett annatDecimal
-objekt. Om inget värde anges returnerasDecimal('0')
. Om värde är en sträng bör den överensstämma med den decimala numeriska strängsyntaxen efter att inledande och avslutande blankstegstecken, samt understrykningstecken, har tagits bort:tecken ::= '+' | '-' siffra ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' indikator ::= 'e' | 'E' siffror ::= siffra [siffra]... decimal-del ::= siffror '.' [siffror] | ['.'] siffror exponent-del ::= indikator [tecken] siffror infinity ::= 'Oändlighet' | 'Inf' nan ::= 'NaN' [siffror] | 'sNaN' [siffror] numeriskt värde ::= decimaldel [exponentdel] | oändlighet numerisk-sträng ::= [tecken] numeriskt-värde | [tecken] nan
Andra Unicode decimalsiffror är också tillåtna där
digit
visas ovan. Dessa inkluderar decimalsiffror från olika andra alfabet (till exempel arabisk-indiska och Devanāgarī-siffror) tillsammans med fullbreddssiffrorna'\uff10
till'\uff19
. Versal är inte signifikant, så till exempelinf
,Inf
,INFINITY
ochiNfINity
är alla acceptabla stavningar för positiv oändlighet.Om värde är en
tuple
ska den ha tre komponenter, ett tecken (0
för positiv eller1
för negativ), entuple
av siffror och en heltalsexponent. Till exempel gerDecimal((0, (1, 4, 1, 4), -3))
Decimal('1.414')
.Om värde är en
float
konverteras det binära flyttalsvärdet förlustfritt till sin exakta decimala motsvarighet. Denna konvertering kan ofta kräva 53 eller fler precisionssiffror. Till exempel konverterarDecimal(float('1.1'))
tillDecimal('1.100000000000000088817841970012523233890533447265625')
.Precisionen i kontexten påverkar inte hur många siffror som lagras. Det bestäms uteslutande av antalet siffror i värdet. Till exempel,
Decimal('3.00000')
registrerar alla fem nollor även om kontextprecisionen bara är tre.Syftet med argumentet context är att bestämma vad som ska göras om value är en felformad sträng. Om kontexten fångar
InvalidOperation
, väcks ett undantag; i annat fall returnerar konstruktören en ny Decimal med värdetNaN
.När
Decimal
-objekt har konstruerats är de oföränderliga.Ändrad i version 3.2: Argumentet till konstruktören får nu vara en
float
-instans.Ändrad i version 3.3:
float
-argument ger upphov till ett undantag omFloatOperation
-fällan är inställd. Som standard är fällan avstängd.Ändrad i version 3.6: Underscores är tillåtna för gruppering, som med integral- och flyttalslitteraler i kod.
Decimala flyttalsobjekt delar många egenskaper med de andra inbyggda numeriska typerna, t.ex.
float
ochint
. Alla vanliga matematiska operationer och specialmetoder gäller. På samma sätt kan decimalobjekt kopieras, betas, skrivas ut, användas som ordboksnycklar, användas som set-element, jämföras, sorteras och tvingas till en annan typ (t.ex.float
ellerint
).Det finns några små skillnader mellan aritmetik på decimalobjekt och aritmetik på heltal och flyttal. När restoperatorn
%
används på decimalobjekt är resultatets tecken tecknet på divisorn i stället för tecknet på divisorn:>>> (-7) % 4 1 >>> Decimal(-7) % Decimal(4) Decimal('-3')
Operatorn för heltalsdivision
//
fungerar på samma sätt och returnerar heltalsdelen av den verkliga kvoten (trunkerad mot noll) i stället för dess golv, så att den vanliga identitetenx == (x // y) * y + x % y
bevaras:>>> -7 // 4 -2 >>> Decimal(-7) // Decimal(4) Decimal('-1')
Operatorerna
%
och//
implementerar operationernaremainder
respektivedivide-integer
enligt beskrivningen i specifikationen.Decimalobjekt kan i allmänhet inte kombineras med float eller instanser av
fractions.Fraction
i aritmetiska operationer: ett försök att lägga till enDecimal
till enfloat
, till exempel, kommer att ge upphov till ettTypeError
. Det är dock möjligt att använda Pythons jämförelseoperatorer för att jämföra enDecimal
-instansx
med ett annat taly
. Detta undviker förvirrande resultat när man gör jämlikhetsjämförelser mellan tal av olika typer.Ändrad i version 3.2: Jämförelser av blandade typer mellan
Decimal
-instanser och andra numeriska typer stöds nu fullt ut.Förutom de numeriska standardegenskaperna har decimala flyttalsobjekt också ett antal specialiserade metoder:
- adjusted()¶
Returnerar den justerade exponenten efter att koefficientens högra siffror har flyttats ut tills endast den första siffran återstår:
Decimal('321e+5').adjusted()
returnerar sju. Används för att bestämma positionen för den mest signifikanta siffran i förhållande till decimaltecknet.
- as_integer_ratio()¶
Returnerar ett par
(n, d)
av heltal som representerar den givnaDecimal
-instansen som ett bråk, i lägsta termer och med en positiv nämnare:>>> Decimal('-3.14').as_integer_ratio() (-157, 50)
Omvandlingen är exakt. Ge upphov till OverflowError för oändligheter och ValueError för NaNs.
Tillagd i version 3.6.
- as_tuple()¶
Returnera en named tuple representation av talet:
DecimalTuple(sign, digits, exponent)
.
- canonical()¶
Returnerar den kanoniska kodningen av argumentet. För närvarande är kodningen av en
Decimal
-instans alltid kanonisk, så denna operation returnerar sitt argument oförändrat.
- compare(other, context=None)¶
Jämför värdena för två decimalinstanser.
compare()
returnerar en decimalinstans, och om någon av operanderna är ett NaN blir resultatet ett NaN:a eller b är en NaN ==> Decimal('NaN') a < b ==> Decimal('-1') a == b ==> Decimal('0') a > b ==> Decimal('1')
- compare_signal(other, context=None)¶
Denna operation är identisk med metoden
compare()
, förutom att alla NaN signalerar. Det vill säga, om ingen av operanderna är ett signalerande NaN, behandlas varje tyst NaN-operand som om det vore ett signalerande NaN.
- compare_total(other, context=None)¶
Jämför två operander med hjälp av deras abstrakta representation snarare än deras numeriska värde. Liknar metoden
compare()
, men resultatet ger en total ordning påDecimal
-instanser. TvåDecimal
-instanser med samma numeriska värde men olika representationer jämförs ojämlikt i denna ordning:>>> Decimal('12.0').compare_total(Decimal('12')) Decimal('-1')
Tysta och signalerande NaNs ingår också i den totala ordningen. Resultatet av denna funktion är
Decimal('0')
om båda operanderna har samma representation,Decimal('-1')
om den första operanden är lägre i den totala ordningen än den andra, ochDecimal('1')
om den första operanden är högre i den totala ordningen än den andra operanden. Se specifikationen för detaljer om den totala ordningen.Denna operation påverkas inte av kontexten och är tyst: inga flaggor ändras och ingen avrundning utförs. Som ett undantag kan C-versionen ge upphov till InvalidOperation om den andra operanden inte kan konverteras exakt.
- compare_total_mag(other, context=None)¶
Jämför två operander med hjälp av deras abstrakta representation i stället för deras värde som i
compare_total()
, men ignorerar tecknet för varje operand.x.compare_total_mag(y)
är ekvivalent medx.copy_abs().compare_total(y.copy_abs())
.Denna operation påverkas inte av kontexten och är tyst: inga flaggor ändras och ingen avrundning utförs. Som ett undantag kan C-versionen ge upphov till InvalidOperation om den andra operanden inte kan konverteras exakt.
- conjugate()¶
Returnerar bara self, denna metod är endast till för att uppfylla Decimal Specification.
- copy_abs()¶
Returnerar argumentets absoluta värde. Denna operation påverkas inte av kontexten och är tyst: inga flaggor ändras och ingen avrundning utförs.
- copy_negate()¶
Returnerar negationen av argumentet. Denna operation påverkas inte av kontexten och är tyst: inga flaggor ändras och ingen avrundning utförs.
- copy_sign(other, context=None)¶
Returnerar en kopia av det första operandet med tecknet satt till samma som tecknet för det andra operandet. Till exempel
>>> Decimal('2.3').copy_sign(Decimal('-1.5')) Decimal('-2.3')
Denna operation påverkas inte av kontexten och är tyst: inga flaggor ändras och ingen avrundning utförs. Som ett undantag kan C-versionen ge upphov till InvalidOperation om den andra operanden inte kan konverteras exakt.
- exp(context=None)¶
Returnerar värdet av den (naturliga) exponentialfunktionen
e**x
vid det angivna talet. Resultatet avrundas korrekt med hjälp av avrundningslägetROUND_HALF_EVEN
.>>> Decimal(1).exp() Decimal('2.718281828459045235360287471') >>> Decimal(321).exp() Decimal('2.561702493119680037517373933E+139')
- classmethod from_float(f)¶
Alternativ konstruktör som endast accepterar instanser av
float
ellerint
.Observera att
Decimal.from_float(0.1)
inte är detsamma somDecimal('0.1')
. Eftersom 0,1 inte är exakt representerbart i binär flyttal lagras värdet som det närmaste representerbara värdet som är0x1.999999999999ap-4
. Det motsvarande värdet i decimal är0.1000000000000000055511151231257827021181583404541015625
.Anteckning
Från Python 3.2 och framåt kan en
Decimal
-instans också konstrueras direkt från enfloat
.>>> Decimal.from_float(0.1) Decimal('0.1000000000000000055511151231257827021181583404541015625') >>> Decimal.from_float(float('nan')) Decimal('NaN') >>> Decimal.from_float(float('inf')) Decimal('Infinity') >>> Decimal.from_float(float('-inf')) Decimal('-Infinity')
Tillagd i version 3.1.
- classmethod from_number(number)¶
Alternativ konstruktör som endast accepterar instanser av
float
,int
ellerDecimal
, men inte strängar eller tupler.>>> Decimal.from_number(314) Decimal('314') >>> Decimal.from_number(0.1) Decimal('0.1000000000000000055511151231257827021181583404541015625') >>> Decimal.from_number(Decimal('3.14')) Decimal('3.14')
Tillagd i version 3.14.
- fma(other, third, context=None)¶
Fusionerad multiplicera-add. Returnera self*other+third utan avrundning av mellanprodukten self*other.
>>> Decimal(2).fma(3, 5) Decimal('11')
- is_canonical()¶
Returnerar
True
om argumentet är kanoniskt ochFalse
annars. För närvarande är enDecimal
-instans alltid kanonisk, så denna operation returnerar alltidTrue
.
- is_finite()¶
Returnerar
True
om argumentet är ett ändligt tal, ochFalse
om argumentet är oändligt eller NaN.
- is_infinite()¶
Returnerar
True
om argumentet är antingen positiv eller negativ oändlighet ochFalse
annars.
- is_normal(context=None)¶
Returnerar
True
om argumentet är ett normalt ändligt tal. ReturnerarFalse
om argumentet är noll, subnormalt, oändligt eller ett NaN.
- is_signed()¶
Returnerar
True
om argumentet har ett negativt tecken ochFalse
annars. Observera att både nollor och NaNs kan ha tecken.
- ln(context=None)¶
Returnerar den naturliga (bas e) logaritmen av operanden. Resultatet avrundas korrekt med hjälp av avrundningsläget
ROUND_HALF_EVEN
.
- log10(context=None)¶
Returnerar bas tio logaritmen av operanden. Resultatet är korrekt avrundat med
ROUND_HALF_EVEN
avrundningsläge.
- logb(context=None)¶
För ett tal som inte är noll, returneras den justerade exponenten för operanden som en
Decimal
-instans. Om operanden är en nolla returnerasDecimal('-Infinity')
och flagganDivisionByZero`
aktiveras. Om operanden är en oändlighet returnerasDecimal('Infinity')
.
- logical_and(other, context=None)¶
logical_and()
är en logisk operation som tar två logiska operander (se Logiska operander). Resultatet är det siffervisaoch
av de två operanderna.
- logical_invert(context=None)¶
logical_invert()
är en logisk operation. Resultatet är den siffermässiga inverteringen av operanden.
- logical_or(other, context=None)¶
logical_or()
är en logisk operation som tar två logiska operander (se Logiska operander). Resultatet är det siffervisaeller
av de två operanderna.
- logical_xor(other, context=None)¶
logical_xor()
är en logisk operation som tar två logiska operander (se Logiska operander). Resultatet är det siffermässigt uteslutande eller av de två operanderna.
- max(other, context=None)¶
Som
max(self, other)
förutom att kontextens avrundningsregel tillämpas innan den returneras och attNaN
-värden antingen signaleras eller ignoreras (beroende på kontexten och om de är signalerande eller tysta).
- max_mag(other, context=None)¶
Påminner om metoden
max()
, men jämförelsen görs med hjälp av operandernas absoluta värden.
- min(other, context=None)¶
Som
min(self, other)
förutom att kontextens avrundningsregel tillämpas innan den returneras och attNaN
-värden antingen signaleras eller ignoreras (beroende på kontexten och om de är signalerande eller tysta).
- min_mag(other, context=None)¶
Påminner om metoden
min()
, men jämförelsen görs med hjälp av operandernas absoluta värden.
- next_minus(context=None)¶
Returnerar det största tal som kan representeras i den givna kontexten (eller i den aktuella trådens kontext om ingen kontext anges) som är mindre än den givna operanden.
- next_plus(context=None)¶
Returnerar det minsta tal som kan representeras i den givna kontexten (eller i den aktuella trådens kontext om ingen kontext anges) som är större än den givna operanden.
- next_toward(other, context=None)¶
Om de två operanderna är olika, returneras det tal som ligger närmast den första operanden i riktning mot den andra operanden. Om båda operanderna är numeriskt lika, returneras en kopia av den första operanden med tecknet satt till samma som tecknet för den andra operanden.
- normalize(context=None)¶
Används för att producera kanoniska värden för en ekvivalensklass inom antingen den aktuella kontexten eller den angivna kontexten.
Detta har samma semantik som den unära plusoperationen, förutom att om slutresultatet är ändligt reduceras det till sin enklaste form, med alla efterföljande nollor borttagna och dess tecken bevarat. Det vill säga, om koefficienten inte är noll och är en multipel av tio divideras koefficienten med tio och exponenten ökas med 1. I annat fall (koefficienten är noll) sätts exponenten till 0. I samtliga fall är tecknet oförändrat.
Till exempel normaliseras
Decimal('32.100')
ochDecimal('0.321000e+2')
båda till det likvärdiga värdetDecimal('32.1')
.Observera att avrundning görs innan reducering till enklaste form.
I de senaste versionerna av specifikationen kallas denna operation även för ”reducera”.
- number_class(context=None)¶
Returnerar en sträng som beskriver operandens klass. Det returnerade värdet är en av följande tio strängar.
"-Infinity"
, vilket indikerar att operanden är negativ oändlighet."-Normal"
, vilket indikerar att operanden är ett negativt normaltal."-Subnormal"
, vilket indikerar att operanden är negativ och subnormal."-Zero"
, vilket indikerar att operanden är en negativ nolla."+Zero"
, vilket indikerar att operanden är en positiv nolla."+Subnormal"
, vilket indikerar att operanden är positiv och subnormal."+Normal"
, vilket indikerar att operanden är ett positivt normalt tal."+Infinity"
, vilket indikerar att operanden är positiv oändlighet."NaN"
, vilket indikerar att operanden är ett tyst NaN (Not a Number)."sNaN"
, vilket indikerar att operanden är en NaN-signal.
- quantize(exp, rounding=None, context=None)¶
Returnerar ett värde som är lika med den första operanden efter avrundning och med den andra operandens exponent.
>>> Decimal('1.41421356').quantize(Decimal('1.000')) Decimal('1.414')
Till skillnad från andra operationer, om koefficientens längd efter kvantiseringsoperationen skulle vara större än precisionen, så signaleras en
InvalidOperation
. Detta garanterar att den kvantiserade exponenten alltid är lika med den högra operandens exponent, såvida inte ett feltillstånd föreligger.Till skillnad från andra operationer signalerar quantize aldrig underflöde, även om resultatet är onormalt och inexakt.
Om exponenten i den andra operanden är större än i den första kan avrundning vara nödvändig. I detta fall bestäms avrundningssättet av argumentet
rounding
om det ges, annars av det givna argumentetcontext
; om inget av argumenten ges används avrundningssättet för den aktuella trådens kontext.Ett fel returneras när den resulterande exponenten är större än
Emax
eller mindre änEtiny()
.
- radix()¶
Returnerar
Decimal(10)
, den radix (bas) i vilkenDecimal
-klassen gör all sin aritmetik. Inkluderad för kompatibilitet med specifikationen.
- remainder_near(other, context=None)¶
Returnerar resten från att dividera self med other. Detta skiljer sig från
self % other
genom att tecknet på återstoden väljs så att dess absoluta värde minimeras. Mer exakt är returvärdetself - n * other
därn
är det heltal som ligger närmast det exakta värdet avself / other
, och om två heltal ligger lika nära väljs det jämna.Om resultatet är noll kommer dess tecken att vara tecknet för själv.
>>> Decimal(18).remainder_near(Decimal(10)) Decimal('-2') >>> Decimal(25).remainder_near(Decimal(10)) Decimal('5') >>> Decimal(35).remainder_near(Decimal(10)) Decimal('-5')
- rotate(other, context=None)¶
Returnerar resultatet av att rotera siffrorna i den första operanden med en mängd som anges av den andra operanden. Det andra operandet måste vara ett heltal i intervallet -precision till precision. Det andra operandets absoluta värde anger antalet platser som ska roteras. Om det andra operandvärdet är positivt sker rotationen åt vänster, annars åt höger. Koefficienten i det första operandet fylls vid behov på vänster sida med nollor för att förlänga precisionen. Tecknet och exponenten för den första operanden är oförändrade.
- same_quantum(other, context=None)¶
Testa om self och other har samma exponent eller om båda är
NaN
.Denna operation påverkas inte av kontexten och är tyst: inga flaggor ändras och ingen avrundning utförs. Som ett undantag kan C-versionen ge upphov till InvalidOperation om den andra operanden inte kan konverteras exakt.
- scaleb(other, context=None)¶
Returnerar den första operanden med exponenten justerad med den andra. På motsvarande sätt returneras den första operanden multiplicerad med
10**annan
. Den andra operanden måste vara ett heltal.
- shift(other, context=None)¶
Returnerar resultatet av att flytta siffrorna i den första operanden med ett belopp som anges av den andra operanden. Det andra operandet måste vara ett heltal i intervallet -precision till precision. Det andra operandets absoluta värde anger antalet platser som ska skiftas. Om det andra operandet är positivt sker förskjutningen åt vänster, annars åt höger. Siffror som flyttas in i koefficienten är nollor. Tecknet och exponenten för den första operanden är oförändrade.
- sqrt(context=None)¶
Returnera kvadratroten av argumentet till full precision.
- to_eng_string(context=None)¶
Konvertera till en sträng, med hjälp av ingenjörsnotation om en exponent behövs.
Teknisk notation har en exponent som är en multipel av 3. Detta kan ge upp till 3 siffror till vänster om decimaltecknet och kan kräva tillägg av antingen en eller två efterföljande nollor.
Detta konverterar till exempel
Decimal('123E+1')
tillDecimal('1.23E+3')
.
- to_integral(rounding=None, context=None)¶
Identisk med metoden
to_integral_value()
. Namnetto_integral
har behållits för kompatibilitet med äldre versioner.
- to_integral_exact(rounding=None, context=None)¶
Avrunda till närmaste heltal, signalera
Inexact
ellerRounded
som lämpligt om avrundning sker. Avrundningsläget bestäms av parameternrounding
om den är angiven, annars av den angivnacontexten
. Om ingen av parametrarna anges används avrundningsläget för den aktuella kontexten.
- to_integral_value(rounding=None, context=None)¶
Avrunda till närmaste heltal utan att signalera
Inexact
ellerRounded
. Om den anges, tillämpas avrundning; annars används avrundningsmetoden i antingen den medföljande kontexten eller den aktuella kontexten.
Decimaltal kan avrundas med hjälp av funktionen
round()
:- round(number)
- round(number, ndigits)
Om ndigits inte anges eller
None
, returneras det närmasteint
till number, med avrundning till jämnt och utan hänsyn till avrundningssättet iDecimal
-kontexten. UtlöserOverflowError
om number är en oändlighet ellerValueError
om det är ett (tyst eller signalerande) NaN.Om ndigits är en
int
, respekteras kontextens avrundningsläge och enDecimal
som representerar tal avrundat till närmaste multipel avDecimal('1E-ndigits')
returneras; i detta fall ärround(number, ndigits)
ekvivalent medself.quantize(Decimal('1E-ndigits'))
. ReturnerarDecimal('NaN')
om tal är ett tyst NaN. UtlöserInvalidOperation
om tal är ett oändligt tal, ett signalerande NaN eller om koefficientens längd efter kvantiseringsoperationen skulle vara större än det aktuella sammanhangets precision. Med andra ord, för de fall som inte är hörnfall:om ndigits är positiv, returnera number avrundat till ndigits decimaler;
om ndigits är noll, returnera number avrundat till närmaste heltal;
om ndigits är negativt, returnera number avrundat till närmaste multipel av
10**abs(ndigits)
.
Till exempel:
>>> from decimal import Decimal, getcontext, ROUND_DOWN >>> getcontext().rounding = ROUND_DOWN >>> round(Decimal('3.75')) # context rounding ignored 4 >>> round(Decimal('3.5')) # round-ties-to-even 4 >>> round(Decimal('3.75'), 0) # uses the context rounding Decimal('3') >>> round(Decimal('3.75'), 1) Decimal('3.7') >>> round(Decimal('3.75'), -1) Decimal('0E+1')
Logiska operander¶
Metoderna logical_and()
, logical_invert()
, logical_or()
och logical_xor()
förväntar sig att deras argument är logiska operander. En logisk operand är en Decimal
-instans vars exponent och tecken båda är noll, och vars siffror alla är antingen 0
eller 1
.
Objekt i kontext¶
Kontexter är miljöer för aritmetiska operationer. De styr precisionen, sätter regler för avrundning, bestämmer vilka signaler som ska behandlas som undantag och begränsar intervallet för exponenter.
Varje tråd har sin egen aktuella kontext som kan nås eller ändras med hjälp av funktionerna getcontext()
och setcontext()
:
- decimal.getcontext()¶
Returnerar det aktuella sammanhanget för den aktiva tråden.
- decimal.setcontext(c)¶
Ställ in det aktuella sammanhanget för den aktiva tråden till c.
Du kan också använda with
-satsen och localcontext()
-funktionen för att tillfälligt ändra den aktiva kontexten.
- decimal.localcontext(ctx=None, **kwargs)¶
Returnerar en kontexthanterare som sätter den aktuella kontexten för den aktiva tråden till en kopia av ctx vid ingången till with-satsen och återställer den tidigare kontexten när with-satsen avslutas. Om ingen kontext anges används en kopia av den aktuella kontexten. Argumentet kwargs används för att ställa in attributen för den nya kontexten.
Följande kod ställer t.ex. in den aktuella decimalprecisionen till 42 enheter, utför en beräkning och återställer sedan automatiskt det tidigare sammanhanget:
från decimal import localcontext med localcontext() som ctx: ctx.prec = 42 # Utför en beräkning med hög precision s = beräkna_något() s = +s # Runda tillbaka slutresultatet till standardprecisionen
Med hjälp av nyckelordsargument skulle koden vara följande:
från decimal import localcontext med localcontext(prec=42) som ctx: s = beräkna_något() s = +s
Utlöser
TypeError
om kwargs anger ett attribut somContext
inte stöder. Utlöser antingenTypeError
ellerValueError
om kwargs anger ett ogiltigt värde för ett attribut.Ändrad i version 3.11:
localcontext()
stöder nu inställning av kontextattribut genom användning av nyckelordsargument.
- decimal.IEEEContext(bits)¶
Returnerar ett kontextobjekt som initierats till rätt värden för ett av IEEE:s utbytesformat. Argumentet måste vara en multipel av 32 och mindre än
IEEE_CONTEXT_MAX_BITS
.Tillagd i version 3.14.
Nya kontexter kan också skapas med hjälp av Context
-konstruktören som beskrivs nedan. Dessutom tillhandahåller modulen tre färdiga kontexter:
- decimal.BasicContext¶
Detta är en standardkontext som definieras av General Decimal Arithmetic Specification. Precisionen är satt till nio. Avrundning är satt till
ROUND_HALF_UP
. Alla flaggor är rensade. Alla traps är aktiverade (behandlas som undantag) utomInexact
,Rounded
ochSubnormal
.Eftersom många av fällorna är aktiverade är detta sammanhang användbart för felsökning.
- decimal.ExtendedContext¶
Detta är en standardkontext som definieras av General Decimal Arithmetic Specification. Precisionen är satt till nio. Avrundning är satt till
ROUND_HALF_EVEN
. Alla flaggor är rensade. Inga fällor är aktiverade (så att undantag inte uppstår under beräkningar).Eftersom fällorna är inaktiverade är detta sammanhang användbart för applikationer som föredrar att ha resultatvärdet
NaN
ellerInfinity
istället för att skapa undantag. Detta gör att en applikation kan slutföra en körning trots förhållanden som annars skulle stoppa programmet.
- decimal.DefaultContext¶
Denna kontext används av
Context
-konstruktören som en prototyp för nya kontexter. Om man ändrar ett fält (t.ex. precision) ändras standardvärdet för nya kontexter som skapas av konstruktörenContext
.Detta sammanhang är mest användbart i flertrådade miljöer. Om du ändrar ett av fälten innan trådarna har startats innebär det att du ställer in systemomfattande standardvärden. Det är inte rekommenderat att ändra fälten efter att trådarna har startat eftersom det kräver trådsynkronisering för att förhindra tävlingsförhållanden.
I enkeltrådade miljöer är det att föredra att inte använda detta sammanhang alls. Skapa istället kontexter explicit enligt beskrivningen nedan.
Standardvärdena är
Context.prec
=``28``,Context.rounding
=ROUND_HALF_EVEN
, och aktiverade fällor förOverflow
,InvalidOperation
, ochDivisionByZero
.
Förutom de tre medföljande kontexterna kan nya kontexter skapas med Context
-konstruktören.
- class decimal.Context(prec=None, rounding=None, Emin=None, Emax=None, capitals=None, clamp=None, flags=None, traps=None)¶
Skapar en ny kontext. Om ett fält inte anges eller är
None
, kopieras standardvärdena frånDefaultContext
. Om fältet flags inte anges eller ärNone
, rensas alla flaggor.- prec¶
Ett heltal i intervallet [
1
,MAX_PREC`
] som anger precisionen för aritmetiska operationer i kontexten.
- rounding¶
En av de konstanter som anges i avsnittet Rounding Modes.
- traps¶
- flags¶
Listor över eventuella signaler som ska ställas in. I allmänhet bör nya kontexter endast ställa in fällor och lämna flaggorna fria.
- Emin¶
- Emax¶
Heltal som anger de yttre gränser som tillåts för exponenter. Emin måste ligga i intervallet [
MIN_EMIN
,0
], Emax i intervallet [0
,MAX_EMAX
].
- capitals¶
Antingen
0
eller1
(standard). Om värdet är satt till1
skrivs exponenter ut med ett stortE
; annars används ett litete
:Decimal('6.02e+23')
.
- clamp¶
Antingen
0
(standard) eller1
. Om den är satt till1
, är exponentene
för enDecimal
-instans som kan representeras i detta sammanhang strikt begränsad till intervalletEmin - prec + 1 <= e <= Emax - prec + 1
. Om clamp är0
gäller ett svagare villkor: den justerade exponenten förDecimal
-instansen är högstEmax
. När clamp är1
kommer ett stort normalt tal, där så är möjligt, att få sin exponent reducerad och ett motsvarande antal nollor tillagda till sin koefficient, för att passa exponentbegränsningarna; detta bevarar talets värde men förlorar information om signifikanta efterföljande nollor. Till exempel:>>> Context(prec=6, Emax=999, clamp=1).create_decimal('1.23e999') Decimal('1.23000E+999')
Ett clamp-värde på
1
ger kompatibilitet med de decimala utbytesformat med fast bredd som anges i IEEE 754.
Klassen
Context
definierar flera metoder för allmänna ändamål samt ett stort antal metoder för att utföra aritmetik direkt i ett givet sammanhang. Dessutom finns det för var och en av deDecimal
-metoder som beskrivs ovan (med undantag för metodernaadjusted()
ochas_tuple()
) en motsvarandeContext
-metod. Till exempel, för enContext
-instansC
ochDecimal
-instansx
, ärC.exp(x)
ekvivalent medx.exp(context=C)
. VarjeContext
-metod accepterar ett Python-heltal (en instans avint
) överallt där en Decimal-instans accepteras.- clear_flags()¶
Återställer alla flaggor till
0
.
- clear_traps()¶
Återställer alla fällor till
0
.Tillagd i version 3.3.
- copy()¶
Returnerar en kopia av kontexten.
- copy_decimal(num)¶
Returnerar en kopia av Decimal-instansen num.
- create_decimal(num)¶
Skapar en ny Decimal-instans från num men använder self som kontext. Till skillnad från
Decimal
-konstruktören tillämpas kontextens precision, avrundningsmetod, flaggor och fällor på konverteringen.Detta är användbart eftersom konstanter ofta ges med större precision än vad som behövs i programmet. En annan fördel är att avrundning omedelbart eliminerar oavsiktliga effekter från siffror som ligger utanför den aktuella precisionen. I följande exempel innebär oavrundade indata att resultatet kan ändras om man lägger till noll i en summa:
>>> getcontext().prec = 3 >>> Decimal('3.4445') + Decimal('1.0023') Decimal('4.45') >>> Decimal('3.4445') + Decimal(0) + Decimal('1.0023') Decimal('4.44')
Denna metod implementerar IBM-specifikationens ”to-number”-operation. Om argumentet är en sträng tillåts inga inledande eller avslutande blanksteg eller understrykningstecken.
- create_decimal_from_float(f)¶
Skapar en ny Decimal-instans från en float f men avrundning med self som kontext. Till skillnad från klassmetoden
Decimal.from_float()
tillämpas kontextens precision, avrundningsmetod, flaggor och fällor på konverteringen.>>> context = Context(prec=5, rounding=ROUND_DOWN) >>> context.create_decimal_from_float(math.pi) Decimal('3.1415') >>> context = Context(prec=5, traps=[Inexact]) >>> context.create_decimal_from_float(math.pi) Traceback (most recent call last): ... decimal.Inexact: None
Tillagd i version 3.1.
- Etiny()¶
Returnerar ett värde lika med
Emin - prec + 1
, vilket är det lägsta exponentvärdet för subnormala resultat. När underflöde inträffar sätts exponenten tillEtiny
.
- Etop()¶
Returnerar ett värde som är lika med
Emax - prec + 1
.
Det vanliga sättet att arbeta med decimaler är att skapa
Decimal
-instanser och sedan tillämpa aritmetiska operationer som äger rum inom den aktuella kontexten för den aktiva tråden. Ett alternativt tillvägagångssätt är att använda kontextmetoder för att beräkna inom en specifik kontext. Metoderna liknar dem för klassenDecimal
och beskrivs bara kortfattat här.- abs(x)¶
Returnerar det absoluta värdet av x.
- add(x, y)¶
Returnera summan av x och y.
- canonical(x)¶
Returnerar samma Decimal-objekt x.
- compare(x, y)¶
Jämför x och y numeriskt.
- compare_signal(x, y)¶
Jämför värdena för de två operanderna numeriskt.
- compare_total(x, y)¶
Jämför två operander med hjälp av deras abstrakta representation.
- compare_total_mag(x, y)¶
Jämför två operander med hjälp av deras abstrakta representation, utan att ta hänsyn till tecken.
- copy_abs(x)¶
Returnerar en kopia av x med tecknet satt till 0.
- copy_negate(x)¶
Returnerar en kopia av x med inverterat tecken.
- copy_sign(x, y)¶
Kopierar tecknet från y till x.
- divide(x, y)¶
Returnera x dividerat med y.
- divide_int(x, y)¶
Returnerar x dividerat med y, trunkerat till ett heltal.
- divmod(x, y)¶
Dividerar två tal och returnerar heltalsdelen av resultatet.
- exp(x)¶
Returnerar
e ** x
.
- fma(x, y, z)¶
Returnerar x multiplicerat med y, plus z.
- is_canonical(x)¶
Returnerar
True
om x är kanonisk; annars returnerasFalse
.
- is_finite(x)¶
Returnerar
True
om x är ändlig; annars returnerasFalse
.
- is_infinite(x)¶
Returnerar
True
om x är oändlig; annars returnerasFalse
.
- is_nan(x)¶
Returnerar
True
om x är en qNaN eller sNaN; annars returnerasFalse
.
- is_normal(x)¶
Returnerar
True
om x är ett normalt tal; annars returnerasFalse
.
- is_qnan(x)¶
Returnerar
True
om x är ett tyst NaN; annars returnerasFalse
.
- is_signed(x)¶
Returnerar
True
om x är negativ; annars returnerasFalse
.
- is_snan(x)¶
Returnerar
True
om x är en signalerande NaN; annars returnerasFalse
.
- is_subnormal(x)¶
Returnerar
True
om x är subnormal; annars returnerasFalse
.
- is_zero(x)¶
Returnerar
True
om x är en nolla; annars returnerasFalse
.
- ln(x)¶
Returnerar den naturliga (bas e) logaritmen för x.
- log10(x)¶
Returnerar bas 10-logaritmen för x.
- logb(x)¶
Returnerar exponenten av magnituden för operandens MSD.
- logical_and(x, y)¶
Använder den logiska operationen och mellan varje operands siffror.
- logical_invert(x)¶
Invertera alla siffrorna i x.
- logical_or(x, y)¶
Tillämpar den logiska operationen eller mellan varje operands siffror.
- logical_xor(x, y)¶
Tillämpar den logiska operationen xor mellan varje operands siffror.
- max(x, y)¶
Jämför två värden numeriskt och returnerar det högsta värdet.
- max_mag(x, y)¶
Jämför värdena numeriskt utan att ta hänsyn till deras tecken.
- min(x, y)¶
Jämför två värden numeriskt och returnerar det lägsta värdet.
- min_mag(x, y)¶
Jämför värdena numeriskt utan att ta hänsyn till deras tecken.
- minus(x)¶
Minus motsvarar den unära prefixoperatorn minus i Python.
- multiply(x, y)¶
Returnera produkten av x och y.
- next_minus(x)¶
Returnerar det största representerbara talet som är mindre än x.
- next_plus(x)¶
Returnerar det minsta representerbara talet som är större än x.
- next_toward(x, y)¶
Returnerar det tal som ligger närmast x, i riktning mot y.
- normalize(x)¶
Reducerar x till sin enklaste form.
- number_class(x)¶
Returnerar en indikation på klassen för x.
- plus(x)¶
Plus motsvarar den unära prefixoperatorn plus i Python. Denna operation tillämpar kontextens precision och avrundning, så det är inte en identitetsoperation.
- power(x, y, modulo=None)¶
Returnerar
x
till potensen avy
, reducerad modulomodulo
om den anges.Beräkna
x**y
med två argument. Omx
är negativt måstey
vara heltal. Resultatet blir inexakt om intey
är heltal och resultatet är ändligt och kan uttryckas exakt i ’precisionssiffror’. Kontextens avrundningsläge används. Resultat avrundas alltid korrekt i Python-versionen.Decimal(0) ** Decimal(0)
resulterar iInvalidOperation
, och omInvalidOperation
inte fångas, resulterar det iDecimal('NaN')
.Ändrad i version 3.3: C-modulen beräknar
power()
i termer av de korrekt avrundade funktionernaexp()
ochln()
. Resultatet är väldefinierat men bara ”nästan alltid korrekt avrundat”.Med tre argument beräkna
(x**y) % modulo
. För formen med tre argument gäller följande restriktioner för argumenten:alla tre argumenten måste vara integrerade
y
måste vara icke-negativminst en av
x
ellery
måste vara icke-nollmodulo
måste vara icke-noll och ha högst ’precision’ siffror
Det värde som erhålls genom
Context.power(x, y, modulo)
är lika med det värde som skulle erhållas genom att beräkna(x**y) % modulo
med obegränsad precision, men beräknas mer effektivt. Resultatets exponent är noll, oavsett exponenterna förx
,y
ochmodulo
. Resultatet är alltid exakt.
- quantize(x, y)¶
Returnerar ett värde som är lika med x (avrundat), med exponenten y.
- radix()¶
Returnerar bara 10, eftersom detta är decimal, :)
- remainder(x, y)¶
Returnerar restvärdet från heltalsdivision.
Om resultatet inte är noll har det samma tecken som den ursprungliga utdelningen.
- remainder_near(x, y)¶
Returnerar
x - y * n
, där n är det heltal som ligger närmast det exakta värdet avx / y
(om resultatet är 0 kommer dess tecken att vara tecknet för x).
- rotate(x, y)¶
Returnerar en roterad kopia av x, y gånger.
- same_quantum(x, y)¶
Returnerar
True
om de två operanderna har samma exponent.
- scaleb(x, y)¶
Returnerar den första operanden efter att ha adderat det andra värdet dess exp.
- shift(x, y)¶
Returnerar en förskjuten kopia av x, y gånger.
- sqrt(x)¶
Kvadratrot av ett icke-negativt tal med kontextprecision.
- subtract(x, y)¶
Returnera skillnaden mellan x och y.
- to_eng_string(x)¶
Konvertera till en sträng, med hjälp av ingenjörsnotation om en exponent behövs.
Teknisk notation har en exponent som är en multipel av 3. Detta kan ge upp till 3 siffror till vänster om decimaltecknet och kan kräva tillägg av antingen en eller två efterföljande nollor.
- to_integral_exact(x)¶
Avrundas till ett heltal.
- to_sci_string(x)¶
Konverterar ett tal till en sträng med vetenskaplig notation.
Konstanter¶
Konstanterna i detta avsnitt är endast relevanta för C-modulen. De ingår också i den rena Python-versionen för kompatibilitet.
32-bitars |
64-bitars |
|
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- decimal.HAVE_THREADS¶
Värdet är
True
. Föråldrad, eftersom Python nu alltid har trådar.Föråldrad sedan version 3.9.
- decimal.HAVE_CONTEXTVAR¶
Standardvärdet är
True
. Om Python ärkonfigurerad med alternativet --without-decimal-contextvar
, använder C-versionen en trådlokal snarare än en koroutinlokal kontext och värdet ärFalse
. Detta är något snabbare i vissa scenarier med nästlade kontexter.Tillagd i version 3.8.3.
Avrundningslägen¶
- decimal.ROUND_CEILING¶
Runda mot
Infinity
.
- decimal.ROUND_DOWN¶
Runda mot noll.
- decimal.ROUND_FLOOR¶
Runda mot
Infinity
.
- decimal.ROUND_HALF_DOWN¶
Avrunda till närmaste med oavgjorda tal mot noll.
- decimal.ROUND_HALF_EVEN¶
Avrunda till närmaste med oavgjort till närmaste jämna heltal.
- decimal.ROUND_HALF_UP¶
Avrunda till närmaste med tiotal som går bort från noll.
- decimal.ROUND_UP¶
Avrunda bort från noll.
- decimal.ROUND_05UP¶
Avrunda bort från noll om sista siffran efter avrundning mot noll skulle ha varit 0 eller 5; annars avrunda mot noll.
Signaler¶
Signalerna representerar förhållanden som uppstår under beräkningen. Var och en motsvarar en kontextflagga och en kontextfälla.
Kontextflaggan sätts närhelst villkoret uppfylls. Efter beräkningen kan flaggorna kontrolleras i informationssyfte (t.ex. för att avgöra om en beräkning var exakt). När du har kontrollerat flaggorna måste du rensa alla flaggor innan du startar nästa beräkning.
Om kontextens trap enabler är inställd för signalen, orsakar villkoret att ett Python-undantag utlöses. Till exempel, om DivisionByZero
-fällan är inställd, kommer ett DivisionByZero
-undantag att utlösas när villkoret påträffas.
- class decimal.Clamped¶
Ändrade en exponent för att passa representationsbegränsningar.
Vanligtvis sker fastspänning när en exponent faller utanför kontextens gränser
Emin
ochEmax
. Om möjligt reduceras exponenten så att den passar genom att nollor läggs till i koefficienten.
- class decimal.DecimalException¶
Basklass för andra signaler och en underklass till
ArithmeticError
.
- class decimal.DivisionByZero¶
Signalerar division av ett icke oändligt tal med noll.
Kan uppstå vid division, modulo-division eller när ett tal upphöjs till en negativ potens. Om denna signal inte fångas upp returneras
Infinity
eller-Infinity
med det tecken som bestäms av ingångarna till beräkningen.
- class decimal.Inexact¶
Indikerar att avrundning har skett och att resultatet inte är exakt.
Signalerar när siffror som inte är noll har tagits bort under avrundningen. Det avrundade resultatet returneras. Signalflaggan eller trap används för att upptäcka när resultaten är inexakta.
- class decimal.InvalidOperation¶
En ogiltig operation utfördes.
Indikerar att en åtgärd begärdes som inte är meningsfull. Om den inte fångas upp returneras
NaN
. Möjliga orsaker inkluderar:Oändlighet - Oändlighet 0 * Infinity Oändlighet / Oändlighet x % 0 Oändligt % x sqrt(-x) och x > 0 0 ** 0 x ** (icke heltal) x ** oändlighet
- class decimal.Overflow¶
Numeriskt överflöde.
Anger att exponenten är större än
Context.Emax
efter att avrundning har skett. Om den inte fångas beror resultatet på avrundningsläget, antingen dras det inåt till det största representativa ändliga talet eller avrundas utåt tillInfinity
. I båda fallen signaleras ocksåInexact
ochRounded
.
- class decimal.Rounded¶
Avrundning skedde, men möjligen gick ingen information förlorad.
Signaleras när avrundning tar bort siffror, även om dessa siffror är noll (t.ex. avrundning av
5,00
till5,0
). Om den inte fångas, returneras resultatet oförändrat. Denna signal används för att upptäcka förlust av signifikanta siffror.
- class decimal.Subnormal¶
Exponent var lägre än
Emin
före avrundning.Inträffar när ett operationsresultat är onormalt (exponenten är för liten). Om det inte fångas, returneras resultatet oförändrat.
- class decimal.Underflow¶
Numeriskt underflöde med resultatet avrundat till noll.
Inträffar när ett subnormalt resultat pressas till noll genom avrundning.
Inexact
ochSubnormal
signaleras också.
- class decimal.FloatOperation¶
Möjliggör striktare semantik för blandning av floats och decimaler.
Om signalen inte är fångad (standard) är det tillåtet att blanda floats och decimaler i
Decimal
-konstruktorn,create_decimal()
och alla jämförelseoperatorer. Både konvertering och jämförelser är exakta. Varje förekomst av en blandad operation registreras tyst genom att ställa inFloatOperation
i kontextflaggorna. Explicita konverteringar medfrom_float()
ellercreate_decimal_from_float()
sätter inte flaggan.I annat fall (signalen fångas upp) är endast jämlikhetsjämförelser och explicita konverteringar tysta. Alla andra blandade operationer ger upphov till
FloatOperation
.
Följande tabell sammanfattar signalernas hierarki:
exceptions.ArithmeticError(exceptions.Exception)
DecimalException
Klämd
DivisionByZero(DecimalException, exceptions.ZeroDivisionError)
Inexakt
Överflöde(Inexakt, Avrundad)
Underflow(Inexact, Rounded, Subnormal)
OgiltigOperation
Avrundad
Subnormal
FloatOperation(DecimalException, undantag.TypeError)
Flyttalsnoteringar¶
Minska avrundningsfel med ökad precision¶
Användningen av decimalt flyttal eliminerar fel i decimalrepresentationen (vilket gör det möjligt att representera 0.1
exakt); vissa operationer kan dock fortfarande medföra avrundningsfel när siffror som inte är noll överstiger den fasta precisionen.
Effekterna av avrundningsfel kan förstärkas genom addition eller subtraktion av nästan motsatta mängder, vilket leder till förlust av signifikans. Knuth ger två instruktiva exempel där avrundad aritmetik med flyttal med otillräcklig precision leder till att de associativa och distributiva egenskaperna hos addition bryts ned:
# Examples from Seminumerical Algorithms, Section 4.2.2.
>>> from decimal import Decimal, getcontext
>>> getcontext().prec = 8
>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
>>> (u + v) + w
Decimal('9.5111111')
>>> u + (v + w)
Decimal('10')
>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
>>> (u*v) + (u*w)
Decimal('0.01')
>>> u * (v+w)
Decimal('0.0060000')
Modulen decimal
gör det möjligt att återställa identiteterna genom att utöka precisionen tillräckligt för att undvika förlust av signifikans:
>>> getcontext().prec = 20
>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
>>> (u + v) + w
Decimal('9.51111111')
>>> u + (v + w)
Decimal('9.51111111')
>>>
>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
>>> (u*v) + (u*w)
Decimal('0.0060000')
>>> u * (v+w)
Decimal('0.0060000')
Särskilda värden¶
Talsystemet för modulen decimal
innehåller specialvärden som NaN
, NaN
, Infinity
, Infinity
och två nollor, +0
och -0
.
Oändligheter kan konstrueras direkt med: Decimal('Infinity')
. De kan också uppstå genom att dividera med noll när signalen DivisionByZero
inte är spärrad. På samma sätt kan oändlighet uppstå när man avrundar bortom gränserna för det största representerbara talet när signalen Overflow
inte fångas upp.
De oändliga talen är signerade (affina) och kan användas i aritmetiska operationer där de behandlas som mycket stora, obestämda tal. Om man t.ex. adderar en konstant till oändligheten får man ett annat oändligt resultat.
Vissa operationer är obestämda och returnerar NaN
, eller om InvalidOperation
-signalen fångas, ger upphov till ett undantag. Till exempel, 0/0
returnerar NaN
vilket betyder ”inte ett tal”. Denna variant av NaN
är tyst och när den väl har skapats kommer den att flöda genom andra beräkningar som alltid resulterar i en annan NaN
. Detta beteende kan vara användbart för en serie beräkningar som ibland saknar indata — det gör att beräkningen kan fortsätta medan specifika resultat flaggas som ogiltiga.
En variant är NaN
som signalerar istället för att vara tyst efter varje operation. Detta är ett användbart returvärde när ett ogiltigt resultat måste avbryta en beräkning för särskild hantering.
Beteendet hos Pythons jämförelseoperatorer kan vara lite förvånande när en NaN
är inblandad. Ett test för likhet där en av operanderna är en tyst eller signalerande NaN
returnerar alltid False`
(även när man gör Decimal('NaN')==Decimal('NaN')
), medan ett test för olikhet alltid returnerar True`
. Ett försök att jämföra två decimaler med någon av operatorerna <
, <=
, >
eller >=
kommer att ge upphov till signalen InvalidOperation
om någon av operanderna är ett NaN
, och returnera False
om denna signal inte fångas upp. Observera att General Decimal Arithmetic-specifikationen inte specificerar beteendet för direkta jämförelser; dessa regler för jämförelser som involverar ett NaN
har hämtats från IEEE 854-standarden (se tabell 3 i avsnitt 5.7). För att säkerställa strikt standardöverensstämmelse, använd metoderna compare()
och compare_signal()
istället.
De signerade nollorna kan uppstå vid beräkningar som underflödar. De behåller det tecken som skulle ha blivit resultatet om beräkningen hade utförts med större precision. Eftersom deras magnitud är noll behandlas både positiva och negativa nollor som lika och deras tecken är informativt.
Förutom de två signerade nollorna, som är olika men ändå lika, finns det olika representationer av noll med olika noggrannhet men ändå likvärdiga i värde. Detta tar lite tid att vänja sig vid. För ett öga som är vant vid normaliserade flyttalsrepresentationer är det inte omedelbart uppenbart att följande beräkning ger ett värde som är lika med noll:
>>> 1 / Decimal('Infinity')
Decimal('0E-1000026')
Arbeta med trådar¶
Funktionen getcontext()
ger åtkomst till ett olika Context
-objekt för varje tråd. Att ha separata trådkontexter innebär att trådar kan göra ändringar (t.ex. getcontext().prec=10
) utan att störa andra trådar.
På samma sätt tilldelar funktionen setcontext()
automatiskt sitt mål till den aktuella tråden.
Om setcontext()
inte har anropats före getcontext()
, kommer getcontext()
automatiskt att skapa en ny kontext för användning i den aktuella tråden. Nya kontextobjekt har standardvärden från decimal.DefaultContext
-objektet.
Flaggan sys.flags.thread_inherit_context
påverkar kontexten för nya trådar. Om flaggan är false kommer nya trådar att starta med en tom kontext. I detta fall kommer getcontext()
att skapa ett nytt kontextobjekt när den anropas och använda standardvärdena från DefaultContext. Om flaggan är true kommer nya trådar att starta med en kopia av kontexten från den som anropar threading.Thread.start()
.
För att styra standardvärdena så att varje tråd använder samma värden i hela applikationen, modifierar du DefaultContext-objektet direkt. Detta bör göras innan några trådar startas så att det inte blir ett race condition mellan trådar som anropar getcontext()
. Till exempel:
# Ställ in applikationsomfattande standardvärden för alla trådar som ska startas
DefaultContext.prec = 12
DefaultContext.avrundning = ROUND_DOWN
DefaultContext.traps = ExtendedContext.traps.copy()
DefaultContext.traps[InvalidOperation] = 1
setcontext(DefaultContext)
# Efteråt kan trådarna startas
t1.start()
t2.start()
t3.start()
. . .
Recept¶
Här är några recept som fungerar som verktygsfunktioner och som visar hur man kan arbeta med klassen Decimal
:
def moneyfmt(value, places=2, curr='', sep=',', dp='.',
pos='', neg='-', trailneg=''):
"""Convert Decimal to a money formatted string.
places: required number of places after the decimal point
curr: optional currency symbol before the sign (may be blank)
sep: optional grouping separator (comma, period, space, or blank)
dp: decimal point indicator (comma or period)
only specify as blank when places is zero
pos: optional sign for positive numbers: '+', space or blank
neg: optional sign for negative numbers: '-', '(', space or blank
trailneg:optional trailing minus indicator: '-', ')', space or blank
>>> d = Decimal('-1234567.8901')
>>> moneyfmt(d, curr='$')
'-$1,234,567.89'
>>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')
'1.234.568-'
>>> moneyfmt(d, curr='$', neg='(', trailneg=')')
'($1,234,567.89)'
>>> moneyfmt(Decimal(123456789), sep=' ')
'123 456 789.00'
>>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')
'<0.02>'
"""
q = Decimal(10) ** -places # 2 places --> '0.01'
sign, digits, exp = value.quantize(q).as_tuple()
result = []
digits = list(map(str, digits))
build, next = result.append, digits.pop
if sign:
build(trailneg)
for i in range(places):
build(next() if digits else '0')
if places:
build(dp)
if not digits:
build('0')
i = 0
while digits:
build(next())
i += 1
if i == 3 and digits:
i = 0
build(sep)
build(curr)
build(neg if sign else pos)
return ''.join(reversed(result))
def pi():
"""Compute Pi to the current precision.
>>> print(pi())
3.141592653589793238462643383
"""
getcontext().prec += 2 # extra digits for intermediate steps
three = Decimal(3) # substitute "three=3.0" for regular floats
lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
while s != lasts:
lasts = s
n, na = n+na, na+8
d, da = d+da, da+32
t = (t * n) / d
s += t
getcontext().prec -= 2
return +s # unary plus applies the new precision
def exp(x):
"""Return e raised to the power of x. Result type matches input type.
>>> print(exp(Decimal(1)))
2.718281828459045235360287471
>>> print(exp(Decimal(2)))
7.389056098930650227230427461
>>> print(exp(2.0))
7.38905609893
>>> print(exp(2+0j))
(7.38905609893+0j)
"""
getcontext().prec += 2
i, lasts, s, fact, num = 0, 0, 1, 1, 1
while s != lasts:
lasts = s
i += 1
fact *= i
num *= x
s += num / fact
getcontext().prec -= 2
return +s
def cos(x):
"""Return the cosine of x as measured in radians.
The Taylor series approximation works best for a small value of x.
For larger values, first compute x = x % (2 * pi).
>>> print(cos(Decimal('0.5')))
0.8775825618903727161162815826
>>> print(cos(0.5))
0.87758256189
>>> print(cos(0.5+0j))
(0.87758256189+0j)
"""
getcontext().prec += 2
i, lasts, s, fact, num, sign = 0, 0, 1, 1, 1, 1
while s != lasts:
lasts = s
i += 2
fact *= i * (i-1)
num *= x * x
sign *= -1
s += num / fact * sign
getcontext().prec -= 2
return +s
def sin(x):
"""Return the sine of x as measured in radians.
The Taylor series approximation works best for a small value of x.
For larger values, first compute x = x % (2 * pi).
>>> print(sin(Decimal('0.5')))
0.4794255386042030002732879352
>>> print(sin(0.5))
0.479425538604
>>> print(sin(0.5+0j))
(0.479425538604+0j)
"""
getcontext().prec += 2
i, lasts, s, fact, num, sign = 1, 0, x, 1, x, 1
while s != lasts:
lasts = s
i += 2
fact *= i * (i-1)
num *= x * x
sign *= -1
s += num / fact * sign
getcontext().prec -= 2
return +s
Decimal FAQ¶
Q. Det är besvärligt att skriva decimal.Decimal('1234.5')
. Finns det något sätt att minimera skrivandet när man använder den interaktiva tolken?
A. Vissa användare förkortar konstruktören till bara en enda bokstav:
>>> D = decimal.Decimal
>>> D('1.23') + D('3.45')
Decimal('4.68')
Q. I en fastpunktsapplikation med två decimaler har vissa indata många decimaler och måste avrundas. Andra ska inte ha överflödiga siffror och måste valideras. Vilka metoder bör användas?
A. Metoden quantize()
avrundar till ett fast antal decimaler. Om Inexact
-fällan är inställd är den också användbar för validering:
>>> TWOPLACES = Decimal(10) ** -2 # same as Decimal('0.01')
>>> # Round to two places
>>> Decimal('3.214').quantize(TWOPLACES)
Decimal('3.21')
>>> # Validate that a number does not exceed two places
>>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Decimal('3.21')
>>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Traceback (most recent call last):
...
Inexact: None
Q. När jag väl har giltiga tvåplatsinmatningar, hur behåller jag den invariansen genom en applikation?
A. Vissa operationer, som addition, subtraktion och multiplikation med ett heltal, bevarar automatiskt fixpunkten. Andra operationer, t.ex. division och multiplikation med annat än heltal, ändrar antalet decimaler och måste följas upp med ett quantize()
-steg:
>>> a = Decimal('102.72') # Initial fixed-point values
>>> b = Decimal('3.17')
>>> a + b # Addition preserves fixed-point
Decimal('105.89')
>>> a - b
Decimal('99.55')
>>> a * 42 # So does integer multiplication
Decimal('4314.24')
>>> (a * b).quantize(TWOPLACES) # Must quantize non-integer multiplication
Decimal('325.62')
>>> (b / a).quantize(TWOPLACES) # And quantize division
Decimal('0.03')
Vid utveckling av fastpunktstillämpningar är det praktiskt att definiera funktioner för att hantera quantize()
-steget:
>>> def mul(x, y, fp=TWOPLACES):
... return (x * y).quantize(fp)
...
>>> def div(x, y, fp=TWOPLACES):
... return (x / y).quantize(fp)
>>> mul(a, b) # Automatically preserve fixed-point
Decimal('325.62')
>>> div(b, a)
Decimal('0.03')
Q. Det finns många sätt att uttrycka samma värde. Siffrorna 200
, 200.000
, 2E2
och .02E+4
har alla samma värde med olika noggrannhet. Finns det något sätt att omvandla dem till ett enda igenkännbart kanoniskt värde?
A. Metoden normalize()
mappar alla likvärdiga värden till en enda representant:
>>> values = map(Decimal, '200 200.000 2E2 .02E+4'.split())
>>> [v.normalize() for v in values]
[Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2')]
Q. När sker avrundning i en beräkning?
A. Det sker efter beräkningen. Filosofin bakom decimalspecifikationen är att tal betraktas som exakta och skapas oberoende av det aktuella sammanhanget. De kan till och med ha större precision än det aktuella sammanhanget. Beräkningar utförs med dessa exakta indata och sedan tillämpas avrundning (eller andra kontextoperationer) på resultatet av beräkningen:
>>> getcontext().prec = 5
>>> pi = Decimal('3.1415926535') # More than 5 digits
>>> pi # All digits are retained
Decimal('3.1415926535')
>>> pi + 0 # Rounded after an addition
Decimal('3.1416')
>>> pi - Decimal('0.00005') # Subtract unrounded numbers, then round
Decimal('3.1415')
>>> pi + 0 - Decimal('0.00005'). # Intermediate values are rounded
Decimal('3.1416')
Q. Vissa decimalvärden skrivs alltid ut med exponentiell notation. Finns det något sätt att få en icke-exponentiell representation?
A. För vissa värden är exponentiell notation det enda sättet att uttrycka antalet signifikanta ställen i koefficienten. Om man t.ex. uttrycker 5,0E+3
som 5000
hålls värdet konstant, men man kan inte visa originalets signifikans på två ställen.
Om en applikation inte bryr sig om att spåra signifikans är det enkelt att ta bort exponenten och de efterföljande nollorna, vilket gör att signifikansen försvinner men värdet förblir oförändrat:
>>> def remove_exponent(d):
... return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()
>>> remove_exponent(Decimal('5E+3'))
Decimal('5000')
Q. Finns det något sätt att konvertera en vanlig float till en Decimal
?
A. Ja, alla binära flyttal kan uttryckas exakt som decimaltal, även om en exakt konvertering kan kräva mer precision än intuitionen skulle föreslå:
>>> Decimal(math.pi)
Decimal('3.141592653589793115997963468544185161590576171875')
Q. Hur kan jag i en komplex beräkning försäkra mig om att jag inte har fått ett felaktigt resultat på grund av otillräcklig precision eller avrundningsavvikelser?
A. Decimalmodulen gör det enkelt att testa resultat. En bra metod är att köra om beräkningarna med större precision och med olika avrundningslägen. Om resultaten skiljer sig mycket åt tyder det på otillräcklig precision, problem med avrundningslägen, dåligt konditionerade indata eller en numeriskt instabil algoritm.
Q. Jag har märkt att kontextprecision tillämpas på resultatet av operationer men inte på indata. Finns det något att se upp med när man blandar värden med olika precisioner?
A. Ja, det stämmer. Principen är att alla värden anses vara exakta och det gäller även aritmetiken för dessa värden. Endast resultaten avrundas. Fördelen med inmatningar är att ”det du skriver är det du får”. En nackdel är att resultaten kan se konstiga ut om man glömmer att indata inte har avrundats:
>>> getcontext().prec = 3
>>> Decimal('3.104') + Decimal('2.104')
Decimal('5.21')
>>> Decimal('3.104') + Decimal('0.000') + Decimal('2.104')
Decimal('5.20')
Lösningen är antingen att öka precisionen eller att tvinga fram avrundning av indata med hjälp av den unära plusoperationen:
>>> getcontext().prec = 3
>>> +Decimal('1.23456789') # unary plus triggers rounding
Decimal('1.23')
Alternativt kan indata avrundas vid skapandet med hjälp av metoden Context.create_decimal()
:
>>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678')
Decimal('1.2345')
Q. Är CPython-implementeringen snabb för stora tal?
A. Ja, det stämmer. I CPython- och PyPy3-implementeringarna integrerar C/CFFI-versionerna av decimalmodulen höghastighetsbiblioteket libmpdec för aritmetik med flytande punkter med godtycklig precision och korrekt avrundad decimal [1]. libmpdec
använder Karatsuba-multiplikation för medelstora tal och Number Theoretic Transform för mycket stora tal.
Kontexten måste anpassas för aritmetik med exakt godtycklig precision. Emin
och Emax
bör alltid sättas till maximala värden, clamp
bör alltid vara 0 (standard). Att ställa in prec
kräver viss försiktighet.
Den enklaste metoden för att prova bignum-aritmetik är att använda det maximala värdet för prec
samt [2]:
>>> setcontext(Context(prec=MAX_PREC, Emax=MAX_EMAX, Emin=MIN_EMIN))
>>> x = Decimal(2) ** 256
>>> x / 128
Decimal('904625697166532776746648320380374280103671755200316906558262375061821325312')
För inexakta resultat är MAX_PREC
alldeles för stor på 64-bitars plattformar och det tillgängliga minnet kommer inte att räcka till:
>>> Decimal(1) / 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
MemoryError
På system med overallokering (t.ex. Linux) är en mer sofistikerad metod att justera prec
till mängden tillgängligt RAM-minne. Anta att du har 8 GB RAM och förväntar dig 10 samtidiga operander som använder maximalt 500 MB vardera:
>>> import sys
>>>
>>> # Maximum number of digits for a single operand using 500MB in 8-byte words
>>> # with 19 digits per word (4-byte and 9 digits for the 32-bit build):
>>> maxdigits = 19 * ((500 * 1024**2) // 8)
>>>
>>> # Check that this works:
>>> c = Context(prec=maxdigits, Emax=MAX_EMAX, Emin=MIN_EMIN)
>>> c.traps[Inexact] = True
>>> setcontext(c)
>>>
>>> # Fill the available precision with nines:
>>> x = Decimal(0).logical_invert() * 9
>>> sys.getsizeof(x)
524288112
>>> x + 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
decimal.Inexact: [<class 'decimal.Inexact'>]
I allmänhet (och i synnerhet i system utan overallokering) rekommenderas att man uppskattar ännu snävare gränser och ställer in Inexact
-fällan om alla beräkningar förväntas vara exakta.