Everywhere on the Internet it always says the decimal.Decimal.is_canonical()
method will return True
if the decimal is canonical.
But what does that even mean? Is it just some term that I do not know?
Contrary to what the other answer claims, canonical
is not related to normalize
. "Canonical" as used in the normalize
docs is not the same as in the canonical
or is_canonical
methods - if it were the same, then normalize
would always return its argument unchanged, as Decimal
instances are always canonical as far as is_canonical
is concerned.
The decimal
module is an implementation of the IBM General Decimal Arithmetic Specification, and Decimal.is_canonical
exists for the sole purpose of implementing that specification's is-canonical
operation. The spec has this to say about is-canonical
:
is-canonical takes one operand. The result is 1 if the operand is canonical; otherwise it is 0. The definition of canonical is implementation-defined; if more than one internal encoding for a given NaN, Infinity, or finite number is possible then one ‘preferred’ encoding is deemed canonical. This operation then tests whether the internal encoding is that preferred encoding.
If all possible operands have just one internal encoding each, then is-canonical always returns 1. This operation is unaffected by context and is quiet – no flags are changed in the context.
If an implementation of the spec has multiple internal encodings of a value, then one encoding is deemed canonical, and is_canonical
tests whether a value is encoded that way. If an implementation (like Python's decimal
module) does not have multiple encodings of the same value, then the operation always reports that the operand is canonical.
Note that the way the spec defines "finite number", Decimal('2.50')
and Decimal('2.5')
are different finite numbers, not different internal encodings of the same number. Finite numbers are defined by a sign, coefficient, and exponent, not by their numerical value. 2.50 has coefficient 250 and exponent -2, while 2.5 has coefficient 25 and exponent -1. Thus, there is no problem with is_canonical
reporting True
for both of these instances.