Decimal math
On Python-ideas, the following question was recently asked
Wouldn’t it be possible to have something along the lines of:
from decimal import TreatFloatsAsDecimal @TreatFloatsAsDecimal a = 0.1 # These are all now decimals b = 0.2 c = 0.3 a + b == c # This now works
The answer is yes, using either an import hook or a custom encoding already implemented as an example. Here we show it in action using the ideas repl: Source code for decimal_math
> py -m ideas -a decimal_math
The following initializing code from ideas is included:
from decimal import Decimal
Ideas Console version 0.2.0. [Python version: 3.11.9]
ideas> 0.1 + 0.2 == 0.3
True
ideas> 0.1 * 10 == 1
True
ideas> 0.1
Decimal('0.1')
ideas> 0.1 + 0.100
Decimal('0.200')
There is a second version of decimal math, whith requires a D suffix after a
float to transform it into a python Decimal.:
Source code for decimal_math_d
> py -m ideas -a decimal_math_d
The following initializing code from ideas is included:
from decimal import Decimal
Ideas Console version 0.2.0. [Python version: 3.11.9]
ideas> 0.1 + 0.2
0.30000000000000004
ideas> 0.1D + 0.2D
Decimal('0.3')
There is actually a third version of decimal math: Source code for decimal_math_with
> py -m ideas -a decimal_math_with
The following initializing code from ideas is included:
from decimal import Decimal
Ideas Console version 0.2.0. [Python version: 3.11.9]
ideas> with float_as_decimal:
... a = 1.0
... b = 2.0
...
Traceback (most recent call last):
File "*Ideas Console*", line 1, in <module>
NameError: name 'float_as_decimal' is not defined
ideas> with float_as_Decimal:
... a = 1.0
... b = 2.0
...
ideas> a, b
(Decimal('1.0'), Decimal('2.0'))
ideas> c = 3.0
ideas> c
3.0
ideas> a, b, c
(Decimal('1.0'), Decimal('2.0'), 3.0)
decimal_math.py
This simply replaces any explicit float by a Decimal. It can be used either as a custom codec or import hook.
decimal_math_d.py
This replaces any explicit float followed by D, by a Decimal.
decimal_math_with.py
Defines a fake context environment in which explicit floats are replaced by decimals.
It does the following transformation:
with float_as_Decimal:
a = 1.0
b = 2.0
c = 3.0
to:
if True: # with float_as_Decimal:
a = Decimal('1.0')
b = Decimal('2.0')
c = 3.0