Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is a decimal considered as 'canonical'?

Everywhere on the Internet it always says the 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?

like image 418
Hacker Avatar asked Mar 02 '23 18:03

Hacker


1 Answers

As @snakecharmerb pointed out, the method will always return True, but I don't believe that makes the question moot. As an aside, why the method always returns True can be seen from looking at method canonical():

Return the canonical encoding of the argument. Currently, the encoding of a Decimal instance is always canonical, so this operation returns its argument unchanged.

But, of course, that does not really shed any more light on the subject. But if we look at method normalize(), we get some insight:

Normalize the number by stripping the rightmost trailing zeros and converting any result equal to Decimal('0') to Decimal('0e0'). Used for producing canonical values for attributes of an equivalence class. For example, Decimal('32.100') and Decimal('0.321000e+2') both normalize to the equivalent value Decimal('32.1').

The above description explains, more or less, what a canonical value is. Also:

Q. There are many ways to express the same value. The numbers 200, 200.000, 2E2, and 02E+4 all have the same value at various precisions. Is there a way to transform them to a single recognizable canonical value?

A. The normalize() method maps all equivalent values to a single representative:

>>> 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')]

Demo of the canonical method

The first 3 Decimal values, but not the 4th, have the same canonical representation because they have the same value and precision.

>>> from decimal import Decimal
>>>
>>> values = map(Decimal, '2E2 .2E+3 .02E+4 20E1'.split())
>>> [v.canonical() for v in values]
[Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2'), Decimal('2.0E+2')]
>>>
like image 168
Booboo Avatar answered Mar 05 '23 17:03

Booboo