cdecimal
The cdecimal module is compatible with decimal.py. Since the official documentation is valid, the rest of this document focuses on the few remaining differences as well as extra features.
Setting Context Values
prec, Emin, Emax, rounding, capitals and clamp are implemented as getters/setters.
An additional field _allcr toggles correct rounding for
exp
,ln
andlog10
. If enabled (default), all methods exceptpower
andinvroot
are correctly rounded.traps and flags have the custom type
SignalDict
, which behaves like a dictionary for most purposes. This is the familiar interface from decimal.py.Internally, traps and flags are just C unsigned integers. cdecimal provides the option to access the integers directly using the getters/setters _traps and _flags.
The use of the two interfaces can be mixed freely. The following table shows how the
SignalDict
items and the C-flags are related:SignalDict C signals C conditions InvalidOperation
DecIEEEInvalidOperation
DecConversionSyntax
DecDivisionImpossible
DecDivisionUndefined
DecInvalidContext
DecInvalidOperation
DecMallocError
Clamped
DecClamped
DecClamped
DivisionByZero
DecDivisionByZero
DecDivisionByZero
FloatOperation
[1]DecFloatOperation
DecFloatOperation
Inexact
DecInexact
DecInexact
Rounded
DecRounded
DecRounded
Subnormal
DecSubnormal
DecSubnormal
Overflow
DecOverflow
DecOverflow
Underflow
DecUnderflow
DecUnderflow
[1] cdecimal extension.
An example of mixing the two interfaces:
>>> from cdecimal import * >>> c = getcontext() # Global (thread-local) context >>> >>> c.traps[Inexact] = True # Trap the Inexact signal >>> c.traps[Inexact] = False # Clear the Inexact signal >>> >>> c._traps |= DecInexact # Trap the Inexact signal >>> c.traps[Inexact] True >>> c._traps &= ~DecInexact # Clear the Inexact signal >>> c.traps[Inexact] False
Context Limits
Module constants:
cdecimal 32-bit cdecimal 64-bit MAX_PREC
425000000
999999999999999999
MAX_EMAX
425000000
999999999999999999
MIN_EMIN
-425000000
-999999999999999999
Valid ranges:
decimal.py cdecimal prec [ 1
,unlimited
][ 1
,MPD_MAX_PREC
]Emax [ 0
,unlimited
][ 0
,MPD_MAX_EMAX
]Emin [ -unlimited
,0
][ MPD_MIN_EMIN
,0
]
Thread Local Default Context
The choice whether the default context is thread local or global is made at
compile time. If thread local contexts are enabled, the module constant
HAVE_THREADS
has a value of 1. Otherwise, the value is 0.
By default, local contexts are enabled.
Decimal Constructor
The Decimal
constructor does not observe the current context, i.e. any
value is read exactly as entered. Since the context of cdecimal has limits,
the following approach is used:
If an Inexact
or Rounded
condition occurs during conversion,
InvalidOperation
is raised and the result is NaN. In this case, the
create_decimal
context method has to be used.
Power Method
The power
method in decimal.py is correctly rounded. cdecimal
currently only guarantees an error less than 1ULP+t, where t has a maximum of
0.1ULP, but is almost always less than 0.01ULP.
FloatOperation Signal
In Python 2.7 and 3.2 the rules for mixing decimals and floats were relaxed. This can give rise to mistakes:
>>> Decimal(1.1) # meaning Decimal("1.1")
Decimal('1.100000000000000088817841970012523233890533447265625')
>>> x = Decimal("1.9")
>>> x > 1.9 # meaning Decimal(1.9)
True
In order to prevent accidental mixing, cdecimal has an additional FloatOperation signal. Here is the behavior with the trap set:
>>> c = getcontext()
>>> c.traps[FloatOperation] = True
>>> Decimal(1.9)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
cdecimal.FloatOperation: [<class 'cdecimal.FloatOperation'>]
>>>
>>> x = Decimal("1.9")
>>> x > 1.9
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
cdecimal.FloatOperation: [<class 'cdecimal.FloatOperation'>]
>>>
For compatibility with decimal.py the FloatOperation signal is off by default. This is the standard behavior for mixed operations across several Python versions:
The same table with the FloatOperation signal enabled:
2.5 2.6 2.7 3.1 3.2 mixed arithmetic TypeError TypeError TypeError TypeError TypeError constructor TypeError TypeError FloatOp TypeError FloatOp __eq__ false false exact false exact __ne__ true true exact true exact ordering FloatOp [5] FloatOp FloatOp FloatOp FloatOp
[2] always false
[3] always true
[4] exact conversions or comparisons
[5] raises FloatOperation
IEEEContext Function
-
cdecimal.
IEEEContext
(bits) Return a context object initialized to the proper values for one of the IEEE interchange formats. The argument must be a multiple of 32 and less than
IEEE_CONTEXT_MAX_BITS
.For the most common values, the following constants are provided:
DECIMAL32
DECIMAL64
DECIMAL128
prec 7
16
34
emax 96
384
6144
emin -95
-383
-6143
round ROUND_HALF_EVEN
ROUND_HALF_EVEN
ROUND_HALF_EVEN
traps 0
0
0
status 0
0
0
newtrap 0
0
0
clamp 1
1
1
allcr 1
1
1