Financial applications and accounting systems cannot tolerate the rounding errors inherent in binary floating-point numbers. The Decimal module provides exact decimal arithmetic, ensuring that $0.10 + $0.20 equals exactly $0.30, not 0.30000000000000004.

Decimal A numeric type that represents decimal numbers exactly as humans write them, avoiding binary floating-point representation errors.

Creating Decimals

Always create Decimals from strings for precision:

create.py
Replay: real traced execution (multi-file project)
# Create Decimal

from decimal import Decimal, getcontext

# Create Decimal
print("Create Decimal:")
# From string (recommended)
d1 = Decimal('10.5')
print(f"From string: {d1}")

# From integer
d2 = Decimal(42)
print(f"From int: {d2}")

# From float (may have precision issues)
d3 = Decimal(10.5)
print(f"From float: {d3}")  # May show extra digits

# Proper way from float
d4 = Decimal(str(10.5))
print(f"From str(float): {d4}")

# Very precise numbers
precise = Decimal('3.14159265358979323846264338327950288419716939937510')
print(f"\nPrecise pi: {precise}")

# Constants
print("\nConstants:")
print(f"Decimal('0'): {Decimal('0')}")
print(f"Decimal('1'): {Decimal('1')}")
print(f"Decimal('Infinity'): {Decimal('Infinity')}")
print(f"Decimal('-Infinity'): {Decimal('-Infinity')}")
print(f"Decimal('NaN'): {Decimal('NaN')}")

# Tuple representation
print("\nTuple representation:")
# (sign, digits, exponent)
d5 = Decimal((0, (1, 2, 3), -2))  # 1.23
print(f"From tuple (0, (1, 2, 3), -2): {d5}")

d6 = Decimal((1, (5, 0), 0))  # -50
print(f"From tuple (1, (5, 0), 0): {d6}")

# Precision context
print("\nPrecision context:")
print(f"Current precision: {getcontext().prec}")
getcontext().prec = 10
result = Decimal('1') / Decimal('3')
print(f"1/3 with prec=10: {result}")

getcontext().prec = 50
result = Decimal('1') / Decimal('3')
print(f"1/3 with prec=50: {result}")

# Reset to default
getcontext().prec = 28

# Convert to other types
print("\nConvert to other types:")
d = Decimal('42.75')
print(f"Decimal: {d}")
print(f"int: {int(d)}")
print(f"float: {float(d)}")
print(f"str: {str(d)}")

# Scientific notation
print("\nScientific notation:")
d7 = Decimal('1.23E+5')
print(f"1.23E+5: {d7}")
d8 = Decimal('4.56E-3')
print(f"4.56E-3: {d8}")

# Compare with float issues
print("\nFloat vs Decimal precision:")
print(f"Float: 0.1 + 0.1 + 0.1 = {0.1 + 0.1 + 0.1}")
print(f"Decimal: 0.1 + 0.1 + 0.1 = {Decimal('0.1') + Decimal('0.1') + Decimal('0.1')}")

print(f"\nFloat: 1.1 + 2.2 = {1.1 + 2.2}")
print(f"Decimal: 1.1 + 2.2 = {Decimal('1.1') + Decimal('2.2')}")

  1. d1 ← 10.5, d2 ← 42, d3 ← 10.5, d4 ← 10.5, precise ← 3.14159265358979323846264338327950288419716939937510

    5# Create Decimal6print("Create Decimal:")7# From string (recommended)8d1→ 10.5 = Decimal('10.5')9print(f"From string: {d110.5}")1011# From integer12d2→ 42 = Decimal(42)13print(f"From int: {d242}")1415# From float (may have precision issues)16d3→ 10.5 = Decimal(10.5)17print(f"From float: {d310.5}")  # May show extra digits1819# Proper way from float20d4→ 10.5 = Decimal(str(10.5))21print(f"From str(float): {d410.5}")2223# Very precise numbers24precise→ 3.14159265358979323846264338327950288419716939937510 = Decimal('3.14159265358979323846264338327950288419716939937510')25print(f"\nPrecise pi: {precise3.14159265358979323846264338327950288419716939937510}")2627# Constants28print("\nConstants:")29print(f"Decimal('0'): {Decimal('0')}")30print(f"Decimal('1'): {Decimal('1')}")31print(f"Decimal('Infinity'): {Decimal('Infinity')}")32print(f"Decimal('-Infinity'): {Decimal('-Infinity')}")33print(f"Decimal('NaN'): {Decimal('NaN')}")3435# Tuple representation36print("\nTuple representation:")37# (sign, digits, exponent)38d5→ 1.23 = Decimal((0, (1, 2, 3), -2))  # 1.2339print(f"From tuple (0, (1, 2, 3), -2): {d51.23}")4041d6→ -50 = Decimal((1, (5, 0), 0))  # -5042print(f"From tuple (1, (5, 0), 0): {d6-50}")4344# Precision context45print("\nPrecision context:")46print(f"Current precision: {getcontext().prec}")47getcontext().prec = 1048result→ 0.3333333333 = Decimal('1') / Decimal('3')49print(f"1/3 with prec=10: {result0.3333333333}")5051getcontext().prec = 5052result→ 0.33333333333333333333333333333333333333333333333333 = Decimal('1') / Decimal('3')53print(f"1/3 with prec=50: {result0.33333333333333333333333333333333333333333333333333}")5455# Reset to default56getcontext().prec = 285758# Convert to other types59print("\nConvert to other types:")60d→ 42.75 = Decimal('42.75')61print(f"Decimal: {d42.75}")62print(f"int: {int(d42.75)}")63print(f"float: {float(d42.75)}")64print(f"str: {str(d42.75)}")6566# Scientific notation67print("\nScientific notation:")68d7→ 1.23E+5 = Decimal('1.23E+5')69print(f"1.23E+5: {d71.23E+5}")70d8→ 0.00456 = Decimal('4.56E-3')71print(f"4.56E-3: {d80.00456}")7273# Compare with float issues74print("\nFloat vs Decimal precision:")75print(f"Float: 0.1 + 0.1 + 0.1 = {0.1 + 0.1 + 0.1}")76print(f"Decimal: 0.1 + 0.1 + 0.1 = {Decimal('0.1') + Decimal('0.1') + Decimal('0.1')}")7778print(f"\nFloat: 1.1 + 2.2 = {1.1 + 2.2}")79print(f"Decimal: 1.1 + 2.2 = {Decimal('1.1') + Decimal('2.2')}")
    outputCreate Decimal:
    From string: 10.5
    From int: 42
    From float: 10.5
    From str(float): 10.5
    
    Precise pi: 3.14159265358979323846264338327950288419716939937510
    
    Constants:
    Decimal('0'): 0
    Decimal('1'): 1
    Decimal('Infinity'): Infinity
    Decimal('-Infinity'): -Infinity
    Decimal('NaN'): NaN
    
    Tuple representation:
    From tuple (0, (1, 2, 3), -2): 1.23
    From tuple (1, (5, 0), 0): -50
    
    Precision context:
    Current precision: 28
    1/3 with prec=10: 0.3333333333
    1/3 with prec=50: 0.33333333333333333333333333333333333333333333333333
    
    Convert to other types:
    Decimal: 42.75
    int: 42
    float: 42.75
    str: 42.75
    
    Scientific notation:
    1.23E+5: 1.23E+5
    4.56E-3: 0.00456
    
    Float vs Decimal precision:
    Float: 0.1 + 0.1 + 0.1 = 0.30000000000000004
    Decimal: 0.1 + 0.1 + 0.1 = 0.3
    
    Float: 1.1 + 2.2 = 3.3000000000000003
    Decimal: 1.1 + 2.2 = 3.3
string initialization Creating Decimal from strings like Decimal('0.1') preserves exact values, while Decimal(0.1) inherits float imprecision.

Arithmetic Operations

Decimal supports all standard arithmetic:

principal
arithmetic.py
Replay: real traced execution (multi-file project)
# Arithmetic operations

from decimal import Decimal, getcontext

# Arithmetic operations
a = Decimal('10.5')
b = Decimal('3.25')

print(f"a = {a}")
print(f"b = {b}")
print()

# Addition
print("Addition:")
print(f"a + b = {a + b}")

# Subtraction
print("\nSubtraction:")
print(f"a - b = {a - b}")

# Multiplication
print("\nMultiplication:")
print(f"a * b = {a * b}")

# Division
print("\nDivision:")
print(f"a / b = {a / b}")

# Floor division
print("\nFloor division:")
print(f"a // b = {a // b}")

# Modulo
print("\nModulo:")
print(f"a % b = {a % b}")

# Power
print("\nPower:")
print(f"a ** 2 = {a ** 2}")
print(f"2 ** 10 = {Decimal('2') ** 10}")

# Negation
print("\nNegation:")
print(f"-a = {-a}")

# Absolute value
print("\nAbsolute value:")
neg = Decimal('-42.5')
print(f"abs({neg}) = {abs(neg)}")

# divmod
print("\ndivmod:")
quotient, remainder = divmod(a, b)
print(f"divmod({a}, {b}) = ({quotient}, {remainder})")

# Chaining operations
print("\nChaining:")
result = Decimal('5') * Decimal('3') + Decimal('10') - Decimal('2')
print(f"5 * 3 + 10 - 2 = {result}")

# Precision in operations
print("\nPrecision in operations:")
getcontext().prec = 10
x = Decimal('1') / Decimal('3')
print(f"1/3 with prec=10: {x}")
print(f"x * 3 = {x * Decimal('3')}")

getcontext().prec = 28  # Reset

# Square root
print("\nSquare root:")
d = Decimal('16')
print(f"sqrt({d}) = {d.sqrt()}")

d2 = Decimal('2')
print(f"sqrt({d2}) = {d2.sqrt()}")

# Exponential and log
print("\nExponential:")
d = Decimal('1')
print(f"exp({d}) = {d.exp()}")

print("\nNatural logarithm:")
d = Decimal('10')
print(f"ln({d}) = {d.ln()}")

print("\nBase-10 logarithm:")
d = Decimal('100')
print(f"log10({d}) = {d.log10()}")

# Compound calculations
print("\nCompound interest:")
principal = Decimal('1000')
rate = Decimal('0.05')
time = 10

amount = principal * (Decimal('1') + rate) ** time
print(f"Principal: ${principal}")
print(f"Rate: {rate * 100}%")
print(f"Time: {time} years")
print(f"Amount: ${amount:.2f}")
print(f"Interest: ${amount - principal:.2f}")

# Precise division
print("\nPrecise division:")
getcontext().prec = 50
result = Decimal('1') / Decimal('7')
print(f"1/7 = {result}")
getcontext().prec = 28  # Reset

# Arithmetic operations

from decimal import Decimal, getcontext

# Arithmetic operations
a = Decimal('10.5')
b = Decimal('3.25')

print(f"a = {a}")
print(f"b = {b}")
print()

# Addition
print("Addition:")
print(f"a + b = {a + b}")

# Subtraction
print("\nSubtraction:")
print(f"a - b = {a - b}")

# Multiplication
print("\nMultiplication:")
print(f"a * b = {a * b}")

# Division
print("\nDivision:")
print(f"a / b = {a / b}")

# Floor division
print("\nFloor division:")
print(f"a // b = {a // b}")

# Modulo
print("\nModulo:")
print(f"a % b = {a % b}")

# Power
print("\nPower:")
print(f"a ** 2 = {a ** 2}")
print(f"2 ** 10 = {Decimal('2') ** 10}")

# Negation
print("\nNegation:")
print(f"-a = {-a}")

# Absolute value
print("\nAbsolute value:")
neg = Decimal('-42.5')
print(f"abs({neg}) = {abs(neg)}")

# divmod
print("\ndivmod:")
quotient, remainder = divmod(a, b)
print(f"divmod({a}, {b}) = ({quotient}, {remainder})")

# Chaining operations
print("\nChaining:")
result = Decimal('5') * Decimal('3') + Decimal('10') - Decimal('2')
print(f"5 * 3 + 10 - 2 = {result}")

# Precision in operations
print("\nPrecision in operations:")
getcontext().prec = 10
x = Decimal('1') / Decimal('3')
print(f"1/3 with prec=10: {x}")
print(f"x * 3 = {x * Decimal('3')}")

getcontext().prec = 28  # Reset

# Square root
print("\nSquare root:")
d = Decimal('16')
print(f"sqrt({d}) = {d.sqrt()}")

d2 = Decimal('2')
print(f"sqrt({d2}) = {d2.sqrt()}")

# Exponential and log
print("\nExponential:")
d = Decimal('1')
print(f"exp({d}) = {d.exp()}")

print("\nNatural logarithm:")
d = Decimal('10')
print(f"ln({d}) = {d.ln()}")

print("\nBase-10 logarithm:")
d = Decimal('100')
print(f"log10({d}) = {d.log10()}")

# Compound calculations
print("\nCompound interest:")
principal = Decimal('500')
rate = Decimal('0.05')
time = 10

amount = principal * (Decimal('1') + rate) ** time
print(f"Principal: ${principal}")
print(f"Rate: {rate * 100}%")
print(f"Time: {time} years")
print(f"Amount: ${amount:.2f}")
print(f"Interest: ${amount - principal:.2f}")

# Precise division
print("\nPrecise division:")
getcontext().prec = 50
result = Decimal('1') / Decimal('7')
print(f"1/7 = {result}")
getcontext().prec = 28  # Reset

# Arithmetic operations

from decimal import Decimal, getcontext

# Arithmetic operations
a = Decimal('10.5')
b = Decimal('3.25')

print(f"a = {a}")
print(f"b = {b}")
print()

# Addition
print("Addition:")
print(f"a + b = {a + b}")

# Subtraction
print("\nSubtraction:")
print(f"a - b = {a - b}")

# Multiplication
print("\nMultiplication:")
print(f"a * b = {a * b}")

# Division
print("\nDivision:")
print(f"a / b = {a / b}")

# Floor division
print("\nFloor division:")
print(f"a // b = {a // b}")

# Modulo
print("\nModulo:")
print(f"a % b = {a % b}")

# Power
print("\nPower:")
print(f"a ** 2 = {a ** 2}")
print(f"2 ** 10 = {Decimal('2') ** 10}")

# Negation
print("\nNegation:")
print(f"-a = {-a}")

# Absolute value
print("\nAbsolute value:")
neg = Decimal('-42.5')
print(f"abs({neg}) = {abs(neg)}")

# divmod
print("\ndivmod:")
quotient, remainder = divmod(a, b)
print(f"divmod({a}, {b}) = ({quotient}, {remainder})")

# Chaining operations
print("\nChaining:")
result = Decimal('5') * Decimal('3') + Decimal('10') - Decimal('2')
print(f"5 * 3 + 10 - 2 = {result}")

# Precision in operations
print("\nPrecision in operations:")
getcontext().prec = 10
x = Decimal('1') / Decimal('3')
print(f"1/3 with prec=10: {x}")
print(f"x * 3 = {x * Decimal('3')}")

getcontext().prec = 28  # Reset

# Square root
print("\nSquare root:")
d = Decimal('16')
print(f"sqrt({d}) = {d.sqrt()}")

d2 = Decimal('2')
print(f"sqrt({d2}) = {d2.sqrt()}")

# Exponential and log
print("\nExponential:")
d = Decimal('1')
print(f"exp({d}) = {d.exp()}")

print("\nNatural logarithm:")
d = Decimal('10')
print(f"ln({d}) = {d.ln()}")

print("\nBase-10 logarithm:")
d = Decimal('100')
print(f"log10({d}) = {d.log10()}")

# Compound calculations
print("\nCompound interest:")
principal = Decimal('2500')
rate = Decimal('0.05')
time = 10

amount = principal * (Decimal('1') + rate) ** time
print(f"Principal: ${principal}")
print(f"Rate: {rate * 100}%")
print(f"Time: {time} years")
print(f"Amount: ${amount:.2f}")
print(f"Interest: ${amount - principal:.2f}")

# Precise division
print("\nPrecise division:")
getcontext().prec = 50
result = Decimal('1') / Decimal('7')
print(f"1/7 = {result}")
getcontext().prec = 28  # Reset

  1. a ← 10.5, b ← 3.25, neg ← -42.5, quotient ← 3, remainder ← 0.75

    5# Arithmetic operations6a→ 10.5 = Decimal('10.5')7b→ 3.25 = Decimal('3.25')89print(f"a = {a10.5}")10print(f"b = {b3.25}")11print()1213# Addition14print("Addition:")15print(f"a + b = {a10.5 + b3.25}")1617# Subtraction18print("\nSubtraction:")19print(f"a - b = {a10.5 - b3.25}")2021# Multiplication22print("\nMultiplication:")23print(f"a * b = {a10.5 * b3.25}")2425# Division26print("\nDivision:")27print(f"a / b = {a10.5 / b3.25}")2829# Floor division30print("\nFloor division:")31print(f"a // b = {a10.5 // b3.25}")3233# Modulo34print("\nModulo:")35print(f"a % b = {a10.5 % b3.25}")3637# Power38print("\nPower:")39print(f"a ** 2 = {a10.5 ** 2}")40print(f"2 ** 10 = {Decimal('2') ** 10}")4142# Negation43print("\nNegation:")44print(f"-a = {-a10.5}")4546# Absolute value47print("\nAbsolute value:")48neg→ -42.5 = Decimal('-42.5')49print(f"abs({neg-42.5}) = {abs(neg)}")5051# divmod52print("\ndivmod:")53quotient→ 3, remainder→ 0.75 = divmod(a10.5, b3.25)54print(f"divmod({a10.5}, {b3.25}) = ({quotient3}, {remainder0.75})")5556# Chaining operations57print("\nChaining:")58result→ 23 = Decimal('5') * Decimal('3') + Decimal('10') - Decimal('2')59print(f"5 * 3 + 10 - 2 = {result23}")6061# Precision in operations62print("\nPrecision in operations:")63getcontext().prec = 1064x→ 0.3333333333 = Decimal('1') / Decimal('3')65print(f"1/3 with prec=10: {x0.3333333333}")66print(f"x * 3 = {x0.3333333333 * Decimal('3')}")6768getcontext().prec = 28  # Reset6970# Square root71print("\nSquare root:")72d→ 16 = Decimal('16')73print(f"sqrt({d16}) = {d.sqrt()}")7475d2→ 2 = Decimal('2')76print(f"sqrt({d22}) = {d2.sqrt()}")7778# Exponential and log79print("\nExponential:")80d→ 1 = Decimal('1')81print(f"exp({d1}) = {d.exp()}")8283print("\nNatural logarithm:")84d→ 10 = Decimal('10')85print(f"ln({d10}) = {d.ln()}")8687print("\nBase-10 logarithm:")88d→ 100 = Decimal('100')89print(f"log10({d100}) = {d.log10()}")9091# Compound calculations92print("\nCompound interest:")93principal→ 1000 = Decimal('1000')  #@principal=Decimal('500'), Decimal('2500')94rate→ 0.05 = Decimal('0.05')95time→ 10 = 109697amount→ 1628.89462677744140625000 = principal1000 * (Decimal('1') + rate0.05) ** time1098print(f"Principal: ${principal1000}")99print(f"Rate: {rate0.05 * 100}%")100print(f"Time: {time10} years")101print(f"Amount: ${amount1628.89462677744140625000:.2f}")102print(f"Interest: ${amount1628.89462677744140625000 - principal1000:.2f}")103104# Precise division105print("\nPrecise division:")106getcontext().prec = 50107result→ 0.14285714285714285714285714285714285714285714285714 = Decimal('1') / Decimal('7')108print(f"1/7 = {result0.14285714285714285714285714285714285714285714285714}")109getcontext().prec = 28  # Reset
    outputa = 10.5
    b = 3.25
    Addition:
    a + b = 13.75
    
    Subtraction:
    a - b = 7.25
    
    Multiplication:
    a * b = 34.125
    
    Division:
    a / b = 3.230769230769230769230769231
    
    Floor division:
    a // b = 3
    
    Modulo:
    a % b = 0.75
    
    Power:
    a ** 2 = 110.25
    2 ** 10 = 1024
    
    Negation:
    -a = -10.5
    
    Absolute value:
    abs(-42.5) = 42.5
    
    divmod:
    divmod(10.5, 3.25) = (3, 0.75)
    
    Chaining:
    5 * 3 + 10 - 2 = 23
    
    Precision in operations:
    1/3 with prec=10: 0.3333333333
    x * 3 = 0.9999999999
    
    Square root:
    sqrt(16) = 4
    sqrt(2) = 1.414213562373095048801688724
    
    Exponential:
    exp(1) = 2.718281828459045235360287471
    
    Natural logarithm:
    ln(10) = 2.302585092994045684017991455
    
    Base-10 logarithm:
    log10(100) = 2
    
    Compound interest:
    Principal: $1000
    Rate: 5.00%
    Time: 10 years
    Amount: $1628.89
    Interest: $628.89
    
    Precise division:
    1/7 = 0.14285714285714285714285714285714285714285714285714
  1. a ← 10.5, b ← 3.25, neg ← -42.5, quotient ← 3, remainder ← 0.75

    5# Arithmetic operations6a→ 10.5 = Decimal('10.5')7b→ 3.25 = Decimal('3.25')89print(f"a = {a10.5}")10print(f"b = {b3.25}")11print()1213# Addition14print("Addition:")15print(f"a + b = {a10.5 + b3.25}")1617# Subtraction18print("\nSubtraction:")19print(f"a - b = {a10.5 - b3.25}")2021# Multiplication22print("\nMultiplication:")23print(f"a * b = {a10.5 * b3.25}")2425# Division26print("\nDivision:")27print(f"a / b = {a10.5 / b3.25}")2829# Floor division30print("\nFloor division:")31print(f"a // b = {a10.5 // b3.25}")3233# Modulo34print("\nModulo:")35print(f"a % b = {a10.5 % b3.25}")3637# Power38print("\nPower:")39print(f"a ** 2 = {a10.5 ** 2}")40print(f"2 ** 10 = {Decimal('2') ** 10}")4142# Negation43print("\nNegation:")44print(f"-a = {-a10.5}")4546# Absolute value47print("\nAbsolute value:")48neg→ -42.5 = Decimal('-42.5')49print(f"abs({neg-42.5}) = {abs(neg)}")5051# divmod52print("\ndivmod:")53quotient→ 3, remainder→ 0.75 = divmod(a10.5, b3.25)54print(f"divmod({a10.5}, {b3.25}) = ({quotient3}, {remainder0.75})")5556# Chaining operations57print("\nChaining:")58result→ 23 = Decimal('5') * Decimal('3') + Decimal('10') - Decimal('2')59print(f"5 * 3 + 10 - 2 = {result23}")6061# Precision in operations62print("\nPrecision in operations:")63getcontext().prec = 1064x→ 0.3333333333 = Decimal('1') / Decimal('3')65print(f"1/3 with prec=10: {x0.3333333333}")66print(f"x * 3 = {x0.3333333333 * Decimal('3')}")6768getcontext().prec = 28  # Reset6970# Square root71print("\nSquare root:")72d→ 16 = Decimal('16')73print(f"sqrt({d16}) = {d.sqrt()}")7475d2→ 2 = Decimal('2')76print(f"sqrt({d22}) = {d2.sqrt()}")7778# Exponential and log79print("\nExponential:")80d→ 1 = Decimal('1')81print(f"exp({d1}) = {d.exp()}")8283print("\nNatural logarithm:")84d→ 10 = Decimal('10')85print(f"ln({d10}) = {d.ln()}")8687print("\nBase-10 logarithm:")88d→ 100 = Decimal('100')89print(f"log10({d100}) = {d.log10()}")9091# Compound calculations92print("\nCompound interest:")93principal→ 500 = Decimal('500')94rate→ 0.05 = Decimal('0.05')95time→ 10 = 109697amount→ 814.44731338872070312500 = principal500 * (Decimal('1') + rate0.05) ** time1098print(f"Principal: ${principal500}")99print(f"Rate: {rate0.05 * 100}%")100print(f"Time: {time10} years")101print(f"Amount: ${amount814.44731338872070312500:.2f}")102print(f"Interest: ${amount814.44731338872070312500 - principal500:.2f}")103104# Precise division105print("\nPrecise division:")106getcontext().prec = 50107result→ 0.14285714285714285714285714285714285714285714285714 = Decimal('1') / Decimal('7')108print(f"1/7 = {result0.14285714285714285714285714285714285714285714285714}")109getcontext().prec = 28  # Reset
    outputa = 10.5
    b = 3.25
    Addition:
    a + b = 13.75
    
    Subtraction:
    a - b = 7.25
    
    Multiplication:
    a * b = 34.125
    
    Division:
    a / b = 3.230769230769230769230769231
    
    Floor division:
    a // b = 3
    
    Modulo:
    a % b = 0.75
    
    Power:
    a ** 2 = 110.25
    2 ** 10 = 1024
    
    Negation:
    -a = -10.5
    
    Absolute value:
    abs(-42.5) = 42.5
    
    divmod:
    divmod(10.5, 3.25) = (3, 0.75)
    
    Chaining:
    5 * 3 + 10 - 2 = 23
    
    Precision in operations:
    1/3 with prec=10: 0.3333333333
    x * 3 = 0.9999999999
    
    Square root:
    sqrt(16) = 4
    sqrt(2) = 1.414213562373095048801688724
    
    Exponential:
    exp(1) = 2.718281828459045235360287471
    
    Natural logarithm:
    ln(10) = 2.302585092994045684017991455
    
    Base-10 logarithm:
    log10(100) = 2
    
    Compound interest:
    Principal: $500
    Rate: 5.00%
    Time: 10 years
    Amount: $814.45
    Interest: $314.45
    
    Precise division:
    1/7 = 0.14285714285714285714285714285714285714285714285714
  1. a ← 10.5, b ← 3.25, neg ← -42.5, quotient ← 3, remainder ← 0.75

    5# Arithmetic operations6a→ 10.5 = Decimal('10.5')7b→ 3.25 = Decimal('3.25')89print(f"a = {a10.5}")10print(f"b = {b3.25}")11print()1213# Addition14print("Addition:")15print(f"a + b = {a10.5 + b3.25}")1617# Subtraction18print("\nSubtraction:")19print(f"a - b = {a10.5 - b3.25}")2021# Multiplication22print("\nMultiplication:")23print(f"a * b = {a10.5 * b3.25}")2425# Division26print("\nDivision:")27print(f"a / b = {a10.5 / b3.25}")2829# Floor division30print("\nFloor division:")31print(f"a // b = {a10.5 // b3.25}")3233# Modulo34print("\nModulo:")35print(f"a % b = {a10.5 % b3.25}")3637# Power38print("\nPower:")39print(f"a ** 2 = {a10.5 ** 2}")40print(f"2 ** 10 = {Decimal('2') ** 10}")4142# Negation43print("\nNegation:")44print(f"-a = {-a10.5}")4546# Absolute value47print("\nAbsolute value:")48neg→ -42.5 = Decimal('-42.5')49print(f"abs({neg-42.5}) = {abs(neg)}")5051# divmod52print("\ndivmod:")53quotient→ 3, remainder→ 0.75 = divmod(a10.5, b3.25)54print(f"divmod({a10.5}, {b3.25}) = ({quotient3}, {remainder0.75})")5556# Chaining operations57print("\nChaining:")58result→ 23 = Decimal('5') * Decimal('3') + Decimal('10') - Decimal('2')59print(f"5 * 3 + 10 - 2 = {result23}")6061# Precision in operations62print("\nPrecision in operations:")63getcontext().prec = 1064x→ 0.3333333333 = Decimal('1') / Decimal('3')65print(f"1/3 with prec=10: {x0.3333333333}")66print(f"x * 3 = {x0.3333333333 * Decimal('3')}")6768getcontext().prec = 28  # Reset6970# Square root71print("\nSquare root:")72d→ 16 = Decimal('16')73print(f"sqrt({d16}) = {d.sqrt()}")7475d2→ 2 = Decimal('2')76print(f"sqrt({d22}) = {d2.sqrt()}")7778# Exponential and log79print("\nExponential:")80d→ 1 = Decimal('1')81print(f"exp({d1}) = {d.exp()}")8283print("\nNatural logarithm:")84d→ 10 = Decimal('10')85print(f"ln({d10}) = {d.ln()}")8687print("\nBase-10 logarithm:")88d→ 100 = Decimal('100')89print(f"log10({d100}) = {d.log10()}")9091# Compound calculations92print("\nCompound interest:")93principal→ 2500 = Decimal('2500')94rate→ 0.05 = Decimal('0.05')95time→ 10 = 109697amount→ 4072.23656694360351562500 = principal2500 * (Decimal('1') + rate0.05) ** time1098print(f"Principal: ${principal2500}")99print(f"Rate: {rate0.05 * 100}%")100print(f"Time: {time10} years")101print(f"Amount: ${amount4072.23656694360351562500:.2f}")102print(f"Interest: ${amount4072.23656694360351562500 - principal2500:.2f}")103104# Precise division105print("\nPrecise division:")106getcontext().prec = 50107result→ 0.14285714285714285714285714285714285714285714285714 = Decimal('1') / Decimal('7')108print(f"1/7 = {result0.14285714285714285714285714285714285714285714285714}")109getcontext().prec = 28  # Reset
    outputa = 10.5
    b = 3.25
    Addition:
    a + b = 13.75
    
    Subtraction:
    a - b = 7.25
    
    Multiplication:
    a * b = 34.125
    
    Division:
    a / b = 3.230769230769230769230769231
    
    Floor division:
    a // b = 3
    
    Modulo:
    a % b = 0.75
    
    Power:
    a ** 2 = 110.25
    2 ** 10 = 1024
    
    Negation:
    -a = -10.5
    
    Absolute value:
    abs(-42.5) = 42.5
    
    divmod:
    divmod(10.5, 3.25) = (3, 0.75)
    
    Chaining:
    5 * 3 + 10 - 2 = 23
    
    Precision in operations:
    1/3 with prec=10: 0.3333333333
    x * 3 = 0.9999999999
    
    Square root:
    sqrt(16) = 4
    sqrt(2) = 1.414213562373095048801688724
    
    Exponential:
    exp(1) = 2.718281828459045235360287471
    
    Natural logarithm:
    ln(10) = 2.302585092994045684017991455
    
    Base-10 logarithm:
    log10(100) = 2
    
    Compound interest:
    Principal: $2500
    Rate: 5.00%
    Time: 10 years
    Amount: $4072.24
    Interest: $1572.24
    
    Precise division:
    1/7 = 0.14285714285714285714285714285714285714285714285714

Precision Context

Control the precision and rounding behavior:

context.py
Replay: real traced execution (multi-file project)
# Context and precision

from decimal import Decimal, getcontext, localcontext, Context, ROUND_HALF_UP, ROUND_DOWN, InvalidOperation

# Context settings
# Get current context
print("Current context:")
ctx = getcontext()
print(f"Precision: {ctx.prec}")
print(f"Rounding: {ctx.rounding}")
print(f"Emin: {ctx.Emin}")
print(f"Emax: {ctx.Emax}")
print()

# Set precision
print("Set precision:")
getcontext().prec = 10
result = Decimal('1') / Decimal('3')
print(f"1/3 with prec=10: {result}")

getcontext().prec = 50
result = Decimal('1') / Decimal('3')
print(f"1/3 with prec=50: {result}")

getcontext().prec = 28  # Reset to default

# Set rounding mode
print("\nSet rounding mode:")
getcontext().rounding = ROUND_HALF_UP
result = Decimal('2.5').quantize(Decimal('1'))
print(f"2.5 with ROUND_HALF_UP: {result}")

getcontext().rounding = ROUND_DOWN
result = Decimal('2.9').quantize(Decimal('1'))
print(f"2.9 with ROUND_DOWN: {result}")

from decimal import ROUND_HALF_EVEN
getcontext().rounding = ROUND_HALF_EVEN  # Reset to default

# Local context (temporary changes)
print("\nLocal context:")
print(f"Global precision: {getcontext().prec}")

with localcontext() as ctx:
    ctx.prec = 5
    result = Decimal('1') / Decimal('7')
    print(f"Inside local context (prec=5): {result}")

result = Decimal('1') / Decimal('7')
print(f"Outside local context: {result}")

# Create custom context
print("\nCustom context:")
custom_ctx = Context(prec=15, rounding=ROUND_DOWN)
with localcontext(custom_ctx):
    result = Decimal('1') / Decimal('3')
    print(f"Custom context (prec=15, ROUND_DOWN): {result}")

# Traps (control exceptions)
print("\nTraps:")
print(f"Default traps: {getcontext().traps}")

# Disable division by zero trap
print("\nDivision by zero:")
with localcontext() as ctx:
    ctx.traps[InvalidOperation] = False
    try:
        result = Decimal('1') / Decimal('0')
        print(f"1/0 = {result}")
        print(f"Is infinite: {result.is_infinite()}")
    except:
        print("Division by zero raised exception")

# Flags (track what happened)
print("\nFlags:")
getcontext().clear_flags()
result = Decimal('1e1000000')
print(f"Flags after overflow: {getcontext().flags}")

# Clamping
print("\nClamping:")
print(f"Clamp: {getcontext().clamp}")

# Copying context
print("\nCopying context:")
ctx1 = getcontext()
ctx2 = ctx1.copy()
ctx2.prec = 10
print(f"Original precision: {ctx1.prec}")
print(f"Copy precision: {ctx2.prec}")

# ExtendedContext (for special operations)
print("\nExtendedContext:")
from decimal import ExtendedContext
with localcontext(ExtendedContext):
    print(f"Extended context precision: {getcontext().prec}")

# Practical examples
print("\n" + "="*50)
print("Practical examples:")

# Financial calculation with controlled precision
print("\nFinancial calculation:")
with localcontext() as ctx:
    ctx.prec = 10
    ctx.rounding = ROUND_HALF_UP

    price = Decimal('19.99')
    tax_rate = Decimal('0.08')
    quantity = 3

    subtotal = price * quantity
    tax = (subtotal * tax_rate).quantize(Decimal('0.01'))
    total = subtotal + tax

    print(f"Price: ${price}")
    print(f"Tax rate: {tax_rate * 100}%")
    print(f"Quantity: {quantity}")
    print(f"Subtotal: ${subtotal}")
    print(f"Tax: ${tax}")
    print(f"Total: ${total:.2f}")

# Scientific calculation with high precision
print("\nScientific calculation:")
with localcontext() as ctx:
    ctx.prec = 100

    # Calculate e using series
    e = Decimal('1')
    factorial = Decimal('1')
    for i in range(1, 50):
        factorial *= i
        e += Decimal('1') / factorial

    print(f"e (100 digits): {e}")

# Currency conversion with rounding
print("\nCurrency conversion:")
with localcontext() as ctx:
    ctx.prec = 28
    ctx.rounding = ROUND_HALF_UP

    usd = Decimal('100.00')
    rate = Decimal('0.85')
    eur = (usd * rate).quantize(Decimal('0.01'))

    print(f"${usd} USD = €{eur} EUR (rate: {rate})")

  1. ctx ← Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])

    6# Get current context7print("Current context:")8ctx→ Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow]) = getcontext()9print(f"Precision: {ctx.prec28}")10print(f"Rounding: {ctx.roundingROUND_HALF_EVEN}")11print(f"Emin: {ctx.Emin-999999}")12print(f"Emax: {ctx.Emax999999}")13print()1415# Set precision16print("Set precision:")17getcontext().prec = 1018result→ 0.3333333333 = Decimal('1') / Decimal('3')19print(f"1/3 with prec=10: {result0.3333333333}")2021getcontext().prec = 5022result→ 0.33333333333333333333333333333333333333333333333333 = Decimal('1') / Decimal('3')23print(f"1/3 with prec=50: {result0.33333333333333333333333333333333333333333333333333}")2425getcontext().prec = 28  # Reset to default2627# Set rounding mode28print("\nSet rounding mode:")29getcontext().rounding = ROUND_HALF_UPROUND_HALF_UP30result→ 3 = Decimal('2.5').quantize(Decimal('1'))31print(f"2.5 with ROUND_HALF_UP: {result3}")3233getcontext().rounding = ROUND_DOWNROUND_DOWN34result→ 2 = Decimal('2.9').quantize(Decimal('1'))35print(f"2.9 with ROUND_DOWN: {result2}")3637from decimal import ROUND_HALF_EVEN38getcontext().rounding = ROUND_HALF_EVENROUND_HALF_EVEN  # Reset to default3940# Local context (temporary changes)41print("\nLocal context:")42print(f"Global precision: {getcontext().prec}")
    outputCurrent context:
    Precision: 28
    Rounding: ROUND_HALF_EVEN
    Emin: -999999
    Emax: 999999
    Set precision:
    1/3 with prec=10: 0.3333333333
    1/3 with prec=50: 0.33333333333333333333333333333333333333333333333333
    
    Set rounding mode:
    2.5 with ROUND_HALF_UP: 3
    2.9 with ROUND_DOWN: 2
    
    Local context:
    Global precision: 28
  2. ctx.prec ← 5, result ← 0.14286

    44with localcontext() as ctx:45    ctx.prec→ 5 = 546    result→ 0.14286 = Decimal('1') / Decimal('7')47    print(f"Inside local context (prec=5): {result0.14286}")
    outputInside local context (prec=5): 0.14286
  3. result ← 0.1428571428571428571428571429, custom_ctx ← Context(prec=15, rounding=ROUND_DOWN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])

    49result→ 0.1428571428571428571428571429 = Decimal('1') / Decimal('7')50print(f"Outside local context: {result0.1428571428571428571428571429}")5152# Create custom context53print("\nCustom context:")54custom_ctx→ Context(prec=15, rounding=ROUND_DOWN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow]) = Context(prec=15, rounding=ROUND_DOWNROUND_DOWN)55with localcontext(custom_ctx):
    outputOutside local context: 0.1428571428571428571428571429
    
    Custom context:
  4. result ← 0.333333333333333

    54custom_ctx = Context(prec=15, rounding=ROUND_DOWN)55with localcontext(custom_ctxContext(prec=15, rounding=ROUND_DOWN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])):56    result→ 0.333333333333333 = Decimal('1') / Decimal('3')57    print(f"Custom context (prec=15, ROUND_DOWN): {result0.333333333333333}")
    outputCustom context (prec=15, ROUND_DOWN): 0.333333333333333
  5. print(" Traps:")

    59# Traps (control exceptions)60print("\nTraps:")61print(f"Default traps: {getcontext().traps}")6263# Disable division by zero trap64print("\nDivision by zero:")65with localcontext() as ctx:
    output
    Traps:
    Default traps: {<class 'decimal.InvalidOperation'>:True, <class 'decimal.FloatOperation'>:False, <class 'decimal.DivisionByZero'>:True, <class 'decimal.Overflow'>:True, <class 'decimal.Underflow'>:False, <class 'decimal.Subnormal'>:False, <class 'decimal.Inexact'>:False, <class 'decimal.Rounded'>:False, <class 'decimal.Clamped'>:False}
    
    Division by zero:
  6. ctx.traps[InvalidOperation] ← False

    64print("\nDivision by zero:")65with localcontext() as ctx:66    ctx.traps[InvalidOperation]→ False = False67    try:
  7. except:

    70    print(f"Is infinite: {result.is_infinite()}")71except:72    print("Division by zero raised exception")
    outputDivision by zero raised exception
    Division by zero raised exception
  8. result ← 1E+1000000, ctx1 ← Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])

    74# Flags (track what happened)75print("\nFlags:")76getcontext().clear_flags()77result→ 1E+1000000 = Decimal('1e1000000')78print(f"Flags after overflow: {getcontext().flags}")7980# Clamping81print("\nClamping:")82print(f"Clamp: {getcontext().clamp}")8384# Copying context85print("\nCopying context:")86ctx1→ Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow]) = getcontext()87ctx2→ Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow]) = ctx1Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow]).copy()88ctx2.prec→ 10 = 1089print(f"Original precision: {ctx1.prec28}")90print(f"Copy precision: {ctx2.prec10}")9192# ExtendedContext (for special operations)93print("\nExtendedContext:")94from decimal import ExtendedContext
    output
    Flags:
    Flags after overflow: {<class 'decimal.InvalidOperation'>:False, <class 'decimal.FloatOperation'>:False, <class 'decimal.DivisionByZero'>:False, <class 'decimal.Overflow'>:False, <class 'decimal.Underflow'>:False, <class 'decimal.Subnormal'>:False, <class 'decimal.Inexact'>:False, <class 'decimal.Rounded'>:False, <class 'decimal.Clamped'>:False}
    
    Clamping:
    Clamp: 0
    
    Copying context:
    Original precision: 28
    Copy precision: 10
    
    ExtendedContext:
  9. with localcontext(ExtendedContext):

    94from decimal import ExtendedContext95with localcontext(ExtendedContextContext(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[])):96    print(f"Extended context precision: {getcontext().prec}")
    outputExtended context precision: 9
  10. print(" " + "="*50)

    98# Practical examples99print("\n" + "="*50)100print("Practical examples:")101102# Financial calculation with controlled precision103print("\nFinancial calculation:")104with localcontext() as ctx:
    output
    ==================================================
    Practical examples:
    
    Financial calculation:
  11. ctx.prec ← 10, ctx.rounding ← ROUND_HALF_UP, price ← 19.99, tax_rate ← 0.08

    103print("\nFinancial calculation:")104with localcontext() as ctx:105    ctx.prec→ 10 = 10106    ctx.rounding→ ROUND_HALF_UP = ROUND_HALF_UPROUND_HALF_UP107    108    price→ 19.99 = Decimal('19.99')109    tax_rate→ 0.08 = Decimal('0.08')110    quantity→ 3 = 3111    112    subtotal→ 59.97 = price19.99 * quantity3113    tax→ 4.80 = (subtotal59.97 * tax_rate0.08).quantize(Decimal('0.01'))114    total→ 64.77 = subtotal59.97 + tax4.80115    116    print(f"Price: ${price19.99}")117    print(f"Tax rate: {tax_rate0.08 * 100}%")118    print(f"Quantity: {quantity3}")119    print(f"Subtotal: ${subtotal59.97}")120    print(f"Tax: ${tax4.80}")121    print(f"Total: ${total64.77:.2f}")
    outputPrice: $19.99
    Tax rate: 8.00%
    Quantity: 3
    Subtotal: $59.97
    Tax: $4.80
    Total: $64.77
  12. print(" Scientific calculation:")

    123# Scientific calculation with high precision124print("\nScientific calculation:")125with localcontext() as ctx:
    output
    Scientific calculation:
  13. ctx.prec ← 100, e ← 1, factorial ← 1

    124print("\nScientific calculation:")125with localcontext() as ctx:126    ctx.prec→ 100 = 100127    128    # Calculate e using series129    e→ 1 = Decimal('1')130    factorial→ 1 = Decimal('1')131    for i in range(1, 50):
  14. e ← 2

    pass 1 of 49
    130factorial = Decimal('1')131for i1 in range(1, 50):132    factorial1 *= i1133    e→ 2 += Decimal('1') / factorial1
    49 passes — pass 1 is the card above
    passiefactorial
    111 21
    222 2.51 2
    332.5 2.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666672 6
    442.666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667 2.7083333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333346 24
    552.708333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333334 2.71666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666724 120
    662.716666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667 2.718055555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555556120 720
    772.718055555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555556 2.718253968253968253968253968253968253968253968253968253968253968253968253968253968253968253968253969720 5040
    882.718253968253968253968253968253968253968253968253968253968253968253968253968253968253968253968253969 2.7182787698412698412698412698412698412698412698412698412698412698412698412698412698412698412698412715040 40320
    992.718278769841269841269841269841269841269841269841269841269841269841269841269841269841269841269841271 2.71828152557319223985890652557319223985890652557319223985890652557319223985890652557319223985890652740320 362880
    ⋯ 38 more passes ⋯
    48482.718281828459045235360287471352662497757247093699959574966967545491804388058265282261751423991371715 2.718281828459045235360287471352662497757247093699959574966967626046565095570637924536703462971667462258623241511168180642964355153611979969197632389120000000000 12413915592536072670862289047373375038521486354677760000000000
    49492.718281828459045235360287471352662497757247093699959574966967626046565095570637924536703462971667462 2.71828182845904523536028747135266249775724709369995957496696762769053980388721695805251881070595921212413915592536072670862289047373375038521486354677760000000000 608281864034267560872252163321295376887552831379210240000000000
  15. print(f"e (100 digits): {e}")

    135print(f"e (100 digits): {e2.718281828459045235360287471352662497757247093699959574966967627690539803887216958052518810705959212}")
    outpute (100 digits): 2.718281828459045235360287471352662497757247093699959574966967627690539803887216958052518810705959212
  16. print(" Currency conversion:")

    137# Currency conversion with rounding138print("\nCurrency conversion:")139with localcontext() as ctx:
    output
    Currency conversion:
  17. ctx.prec ← 28, ctx.rounding ← ROUND_HALF_UP, usd ← 100.00, rate ← 0.85

    138print("\nCurrency conversion:")139with localcontext() as ctx:140    ctx.prec→ 28 = 28141    ctx.rounding→ ROUND_HALF_UP = ROUND_HALF_UPROUND_HALF_UP142    143    usd→ 100.00 = Decimal('100.00')144    rate→ 0.85 = Decimal('0.85')145    eur→ 85.00 = (usd100.00 * rate0.85).quantize(Decimal('0.01'))146    147    print(f"${usd100.00} USD = €{eur85.00} EUR (rate: {rate0.85})")
    output$100.00 USD = €85.00 EUR (rate: 0.85)
getcontext() The decimal context controls precision, rounding mode, and error handling for all Decimal operations in the current thread.

Rounding Methods

Different rounding modes for different needs:

rounding.py
Replay: real traced execution (multi-file project)
# Rounding modes

from decimal import Decimal, getcontext, ROUND_CEILING, ROUND_FLOOR, ROUND_UP, ROUND_DOWN, ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_05UP

# Rounding modes
value = Decimal('2.5')

print(f"Value: {value}")
print()

# quantize for rounding
print("Rounding 2.5:")
print(f"ROUND_CEILING (up): {value.quantize(Decimal('1'), rounding=ROUND_CEILING)}")
print(f"ROUND_FLOOR (down): {value.quantize(Decimal('1'), rounding=ROUND_FLOOR)}")
print(f"ROUND_UP (away from 0): {value.quantize(Decimal('1'), rounding=ROUND_UP)}")
print(f"ROUND_DOWN (toward 0): {value.quantize(Decimal('1'), rounding=ROUND_DOWN)}")
print(f"ROUND_HALF_UP: {value.quantize(Decimal('1'), rounding=ROUND_HALF_UP)}")
print(f"ROUND_HALF_DOWN: {value.quantize(Decimal('1'), rounding=ROUND_HALF_DOWN)}")
print(f"ROUND_HALF_EVEN (banker's): {value.quantize(Decimal('1'), rounding=ROUND_HALF_EVEN)}")

# Different values
print("\nRounding different values:")
values = [Decimal('2.4'), Decimal('2.5'), Decimal('2.6'), Decimal('-2.5')]
for val in values:
    print(f"{val}: HALF_UP={val.quantize(Decimal('1'), rounding=ROUND_HALF_UP)}, "
          f"HALF_EVEN={val.quantize(Decimal('1'), rounding=ROUND_HALF_EVEN)}")

# Round to decimal places
print("\nRound to decimal places:")
pi = Decimal('3.14159265358979323846')
print(f"Original: {pi}")
print(f"2 places: {pi.quantize(Decimal('0.01'))}")
print(f"4 places: {pi.quantize(Decimal('0.0001'))}")
print(f"6 places: {pi.quantize(Decimal('0.000001'))}")

# Round to significant figures using context
print("\nRound to significant figures:")
getcontext().prec = 3
large = Decimal('12345.6789')
rounded = +large  # Unary plus applies rounding
print(f"12345.6789 to 3 sig figs: {rounded}")

getcontext().prec = 5
rounded = +large
print(f"12345.6789 to 5 sig figs: {rounded}")

getcontext().prec = 28  # Reset

# Context rounding mode
print("\nContext rounding mode:")
getcontext().rounding = ROUND_UP
result = Decimal('10') / Decimal('3')
print(f"10/3 with ROUND_UP: {result}")

getcontext().rounding = ROUND_DOWN
result = Decimal('10') / Decimal('3')
print(f"10/3 with ROUND_DOWN: {result}")

getcontext().rounding = ROUND_HALF_EVEN  # Reset

# Financial rounding
print("\nFinancial rounding (2 decimals):")
prices = [Decimal('19.995'), Decimal('19.994'), Decimal('19.996')]
for price in prices:
    rounded = price.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    print(f"${price} -> ${rounded}")

# Round to nearest 5 cents
print("\nRound to nearest 5 cents:")
amounts = [Decimal('1.23'), Decimal('1.27'), Decimal('1.28')]
nickel = Decimal('0.05')
for amount in amounts:
    rounded = (amount / nickel).quantize(Decimal('1'), rounding=ROUND_HALF_UP) * nickel
    print(f"${amount} -> ${rounded}")

# Truncate (no rounding)
print("\nTruncate decimals:")
value = Decimal('123.456789')
truncated = value.quantize(Decimal('0.01'), rounding=ROUND_DOWN)
print(f"{value} truncated to 2 places: {truncated}")

# Round to nearest hundred
print("\nRound to nearest hundred:")
amount = Decimal('12345')
hundred = Decimal('100')
rounded = (amount / hundred).quantize(Decimal('1'), rounding=ROUND_HALF_UP) * hundred
print(f"{amount} -> {rounded}")

# Custom rounding
def round_decimal(value, places, mode=ROUND_HALF_UP):
    """Round Decimal to specified places."""
    if places < 0:
        # Round to tens, hundreds, etc.
        factor = Decimal(10) ** abs(places)
        return (value / factor).quantize(Decimal('1'), rounding=mode) * factor
    else:
        quantizer = Decimal(10) ** -places
        return value.quantize(quantizer, rounding=mode)

print("\nCustom rounding function:")
val = Decimal('12345.6789')
print(f"Original: {val}")
print(f"2 places: {round_decimal(val, 2)}")
print(f"0 places: {round_decimal(val, 0)}")
print(f"-2 places (hundreds): {round_decimal(val, -2)}")

  1. value ← 2.5, values ← [Decimal('2.4'), Decimal('2.5'), Decimal('2.6'), Decimal('-2.5')]

    5# Rounding modes6value→ 2.5 = Decimal('2.5')78print(f"Value: {value2.5}")9print()1011# quantize for rounding12print("Rounding 2.5:")13print(f"ROUND_CEILING (up): {value2.5.quantize(Decimal('1'), rounding=ROUND_CEILINGROUND_CEILING)}")14print(f"ROUND_FLOOR (down): {value2.5.quantize(Decimal('1'), rounding=ROUND_FLOORROUND_FLOOR)}")15print(f"ROUND_UP (away from 0): {value2.5.quantize(Decimal('1'), rounding=ROUND_UPROUND_UP)}")16print(f"ROUND_DOWN (toward 0): {value2.5.quantize(Decimal('1'), rounding=ROUND_DOWNROUND_DOWN)}")17print(f"ROUND_HALF_UP: {value2.5.quantize(Decimal('1'), rounding=ROUND_HALF_UPROUND_HALF_UP)}")18print(f"ROUND_HALF_DOWN: {value2.5.quantize(Decimal('1'), rounding=ROUND_HALF_DOWNROUND_HALF_DOWN)}")19print(f"ROUND_HALF_EVEN (banker's): {value2.5.quantize(Decimal('1'), rounding=ROUND_HALF_EVENROUND_HALF_EVEN)}")2021# Different values22print("\nRounding different values:")23values→ [Decimal('2.4'), Decimal('2.5'), Decimal('2.6'), Decimal('-2.5')] = [Decimal('2.4'), Decimal('2.5'), Decimal('2.6'), Decimal('-2.5')]24for val in values:
    outputValue: 2.5
    Rounding 2.5:
    ROUND_CEILING (up): 3
    ROUND_FLOOR (down): 2
    ROUND_UP (away from 0): 3
    ROUND_DOWN (toward 0): 2
    ROUND_HALF_UP: 3
    ROUND_HALF_DOWN: 2
    ROUND_HALF_EVEN (banker's): 2
    
    Rounding different values:
  2. for val in values:

    pass 1 of 4
    23values = [Decimal('2.4'), Decimal('2.5'), Decimal('2.6'), Decimal('-2.5')]24for val2.4 in values[Decimal('2.4'), Decimal('2.5'), Decimal('2.6'), Decimal('-2.5')]:25    print(f"{val2.4}: HALF_UP={val.quantize(Decimal('1'), rounding=ROUND_HALF_UPROUND_HALF_UP)}, "26          f"HALF_EVEN={val2.4.quantize(Decimal('1'), rounding=ROUND_HALF_EVENROUND_HALF_EVEN)}")
    output2.4: HALF_UP=2, HALF_EVEN=2
    All 4 passes — pass 1 is the card above
    passval
    12.4
    22.5
    32.6
    4-2.5
  3. pi ← 3.14159265358979323846, large ← 12345.6789, rounded ← 1.23E+4

    28# Round to decimal places29print("\nRound to decimal places:")30pi→ 3.14159265358979323846 = Decimal('3.14159265358979323846')31print(f"Original: {pi3.14159265358979323846}")32print(f"2 places: {pi3.14159265358979323846.quantize(Decimal('0.01'))}")33print(f"4 places: {pi3.14159265358979323846.quantize(Decimal('0.0001'))}")34print(f"6 places: {pi3.14159265358979323846.quantize(Decimal('0.000001'))}")3536# Round to significant figures using context37print("\nRound to significant figures:")38getcontext().prec = 339large→ 12345.6789 = Decimal('12345.6789')40rounded→ 1.23E+4 = +large12345.6789  # Unary plus applies rounding41print(f"12345.6789 to 3 sig figs: {rounded1.23E+4}")4243getcontext().prec = 544rounded→ 12346 = +large12345.678945print(f"12345.6789 to 5 sig figs: {rounded12346}")4647getcontext().prec = 28  # Reset4849# Context rounding mode50print("\nContext rounding mode:")51getcontext().rounding = ROUND_UPROUND_UP52result→ 3.333333333333333333333333334 = Decimal('10') / Decimal('3')53print(f"10/3 with ROUND_UP: {result3.333333333333333333333333334}")5455getcontext().rounding = ROUND_DOWNROUND_DOWN56result→ 3.333333333333333333333333333 = Decimal('10') / Decimal('3')57print(f"10/3 with ROUND_DOWN: {result3.333333333333333333333333333}")5859getcontext().rounding = ROUND_HALF_EVENROUND_HALF_EVEN  # Reset6061# Financial rounding62print("\nFinancial rounding (2 decimals):")63prices→ [Decimal('19.995'), Decimal('19.994'), Decimal('19.996')] = [Decimal('19.995'), Decimal('19.994'), Decimal('19.996')]64for price in prices:
    output
    Round to decimal places:
    Original: 3.14159265358979323846
    2 places: 3.14
    4 places: 3.1416
    6 places: 3.141593
    
    Round to significant figures:
    12345.6789 to 3 sig figs: 1.23E+4
    12345.6789 to 5 sig figs: 12346
    
    Context rounding mode:
    10/3 with ROUND_UP: 3.333333333333333333333333334
    10/3 with ROUND_DOWN: 3.333333333333333333333333333
    
    Financial rounding (2 decimals):
  4. rounded ← 20.00

    pass 1 of 3
    63prices = [Decimal('19.995'), Decimal('19.994'), Decimal('19.996')]64for price19.995 in prices[Decimal('19.995'), Decimal('19.994'), Decimal('19.996')]:65    rounded→ 20.00 = price19.995.quantize(Decimal('0.01'), rounding=ROUND_HALF_UPROUND_HALF_UP)66    print(f"${price19.995} -> ${rounded20.00}")
    output$19.995 -> $20.00
    All 3 passes — pass 1 is the card above
    passpricerounded
    119.99520.00
    219.99419.99
    319.99620.00
  5. amounts ← [Decimal('1.23'), Decimal('1.27'), Decimal('1.28')]

    68# Round to nearest 5 cents69print("\nRound to nearest 5 cents:")70amounts→ [Decimal('1.23'), Decimal('1.27'), Decimal('1.28')] = [Decimal('1.23'), Decimal('1.27'), Decimal('1.28')]71nickel→ 0.05 = Decimal('0.05')72for amount in amounts:
    output
    Round to nearest 5 cents:
  6. rounded ← 1.25

    pass 1 of 3
    71nickel = Decimal('0.05')72for amount1.23 in amounts[Decimal('1.23'), Decimal('1.27'), Decimal('1.28')]:73    rounded→ 1.25 = (amount1.23 / nickel0.05).quantize(Decimal('1'), rounding=ROUND_HALF_UPROUND_HALF_UP) * nickel74    print(f"${amount1.23} -> ${rounded1.25}")
    output$1.23 -> $1.25
    All 3 passes — pass 1 is the card above
    passamountrounded
    11.231.25
    21.271.25
    31.281.30
  7. value ← 123.456789, truncated ← 123.45, amount ← 12345, hundred ← 100

    76# Truncate (no rounding)77print("\nTruncate decimals:")78value→ 123.456789 = Decimal('123.456789')79truncated→ 123.45 = value123.456789.quantize(Decimal('0.01'), rounding=ROUND_DOWNROUND_DOWN)80print(f"{value123.456789} truncated to 2 places: {truncated123.45}")8182# Round to nearest hundred83print("\nRound to nearest hundred:")84amount→ 12345 = Decimal('12345')85hundred→ 100 = Decimal('100')86rounded→ 12300 = (amount12345 / hundred100).quantize(Decimal('1'), rounding=ROUND_HALF_UPROUND_HALF_UP) * hundred87print(f"{amount12345} -> {rounded12300}")8889# Custom rounding90def round_decimal(value, places, mode=ROUND_HALF_UP):91    """Round Decimal to specified places."""92    if places < 0:93        # Round to tens, hundreds, etc.94        factor = Decimal(10) ** abs(places)95        return (value / factor).quantize(Decimal('1'), rounding=mode) * factor96    else:97        quantizer = Decimal(10) ** -places98        return value.quantize(quantizer, rounding=mode)99100print("\nCustom rounding function:")101val→ 12345.6789 = Decimal('12345.6789')102print(f"Original: {val12345.6789}")103print(f"2 places: {round_decimal(val12345.6789, 2)}")104print(f"0 places: {round_decimal(val, 0)}")
    output
    Truncate decimals:
    123.456789 truncated to 2 places: 123.45
    
    Round to nearest hundred:
    12345 -> 12300
    
    Custom rounding function:
    Original: 12345.6789
  8. def round_decimal(value, places, mode=ROUND_HALF_UP):

    pass 1 of 3
    89# Custom rounding90def round_decimal(value12345.6789, places2, modeROUND_HALF_UP=ROUND_HALF_UPROUND_HALF_UP):91    """Round Decimal to specified places."""92    if places < 0:
    All 3 passes — pass 1 is the card above
    passplacesquantizerfactor
    120.01
    201
    3-2100
  9. quantizer ← 0.01

    pass 1 of 2
    94    factor = Decimal(10) ** abs(places)95    return (value / factor).quantize(Decimal('1'), rounding=mode) * factor96else:97    quantizer→ 0.01 = Decimal(10) ** -places298    return value12345.6789.quantize(quantizer0.01, rounding=modeROUND_HALF_UP)
  10. print(f"2 places: {round_decimal(val, 2)}")

    102print(f"Original: {val}")103print(f"2 places: {round_decimal(val12345.6789, 2)}")104print(f"0 places: {round_decimal(val12345.6789, 0)}")105print(f"-2 places (hundreds): {round_decimal(val, -2)}")
    output2 places: 12345.68
  11. quantizer ← 1

    pass 2 of 2
    94    factor = Decimal(10) ** abs(places)95    return (value / factor).quantize(Decimal('1'), rounding=mode) * factor96else:97    quantizer→ 1 = Decimal(10) ** -places098    return value12345.6789.quantize(quantizer1, rounding=modeROUND_HALF_UP)
  12. print(f"0 places: {round_decimal(val, 0)}")

    103print(f"2 places: {round_decimal(val, 2)}")104print(f"0 places: {round_decimal(val12345.6789, 0)}")105print(f"-2 places (hundreds): {round_decimal(val12345.6789, -2)}")
    output0 places: 12346
  13. factor ← 100

    91"""Round Decimal to specified places."""92if places-2 < 0:93    # Round to tens, hundreds, etc.94    factor→ 100 = Decimal(10) ** abs(places-2)95    return (value12345.6789 / factor100).quantize(Decimal('1'), rounding=modeROUND_HALF_UP) * factor96else:
  14. print(f"-2 places (hundreds): {round_decimal(val, -2)}")

    104print(f"0 places: {round_decimal(val, 0)}")105print(f"-2 places (hundreds): {round_decimal(val12345.6789, -2)}")
    output-2 places (hundreds): 12300

Comparison Operations

Comparing Decimal values:

comparison.py
Replay: real traced execution (multi-file project)
# Comparison operations

from decimal import Decimal

# Comparison
a = Decimal('10.5')
b = Decimal('20.3')
c = Decimal('10.5')

print(f"a = {a}")
print(f"b = {b}")
print(f"c = {c}")
print()

# Equality
print("Equality:")
print(f"a == b: {a == b}")
print(f"a == c: {a == c}")
print(f"a != b: {a != b}")

# Ordering
print("\nOrdering:")
print(f"a < b: {a < b}")
print(f"a <= b: {a <= b}")
print(f"a > b: {a > b}")
print(f"a >= b: {a >= b}")

# compare method
print("\ncompare method:")
print(f"a.compare(b): {a.compare(b)}")  # -1, 0, or 1
print(f"b.compare(a): {b.compare(a)}")
print(f"a.compare(c): {a.compare(c)}")

# compare_signal (raises on NaN)
print("\ncompare_signal:")
print(f"a.compare_signal(b): {a.compare_signal(b)}")

# max and min
print("\nmax and min:")
print(f"max(a, b): {max(a, b)}")
print(f"min(a, b): {min(a, b)}")

# Decimal max/min methods
print("\nDecimal max/min methods:")
print(f"a.max(b): {a.max(b)}")
print(f"a.min(b): {a.min(b)}")

# Find max/min in list
print("\nFind max/min in list:")
numbers = [Decimal('12.5'), Decimal('45.2'), Decimal('23.7'), Decimal('89.1')]
print(f"Numbers: {numbers}")
print(f"Max: {max(numbers)}")
print(f"Min: {min(numbers)}")

# Sort
print("\nSort:")
sorted_nums = sorted(numbers)
print(f"Sorted: {sorted_nums}")

# Check if in range
print("\nCheck if in range:")
value = Decimal('15.5')
lower = Decimal('10')
upper = Decimal('20')
in_range = lower <= value <= upper
print(f"{value} in [{lower}, {upper}]: {in_range}")

# Zero checks
print("\nZero checks:")
zero = Decimal('0')
pos = Decimal('5')
neg = Decimal('-5')

print(f"{zero} == 0: {zero == 0}")
print(f"{pos} > 0: {pos > 0}")
print(f"{neg} < 0: {neg < 0}")

# is_zero method
print("\nis_zero method:")
print(f"{zero}.is_zero(): {zero.is_zero()}")
print(f"{pos}.is_zero(): {pos.is_zero()}")

# Sign checks
print("\nSign checks:")
print(f"{pos}.is_signed(): {pos.is_signed()}")
print(f"{neg}.is_signed(): {neg.is_signed()}")
print(f"{zero}.is_signed(): {zero.is_signed()}")

# is_finite, is_infinite, is_nan
print("\nSpecial value checks:")
finite = Decimal('42.5')
infinity = Decimal('Infinity')
nan = Decimal('NaN')

print(f"{finite}.is_finite(): {finite.is_finite()}")
print(f"{infinity}.is_infinite(): {infinity.is_infinite()}")
print(f"{nan}.is_nan(): {nan.is_nan()}")

# is_normal, is_subnormal
print("\nis_normal:")
normal = Decimal('1.5')
tiny = Decimal('1e-1000')
print(f"{normal}.is_normal(): {normal.is_normal()}")
print(f"{tiny}.is_normal(): {tiny.is_normal()}")

# compare_total (considers exponent)
print("\ncompare_total (considers exponent):")
d1 = Decimal('1.0')
d2 = Decimal('1.00')
print(f"d1 = {d1}, d2 = {d2}")
print(f"d1 == d2: {d1 == d2}")  # True (value equal)
print(f"d1.compare_total(d2): {d1.compare_total(d2)}")  # -1 (exponents differ)

# Tolerance comparison (for floats converted to Decimal)
print("\nTolerance comparison:")
def approx_equal(a, b, tolerance=Decimal('0.0001')):
    """Check if two Decimals are approximately equal."""
    return abs(a - b) <= tolerance

val1 = Decimal('3.14159')
val2 = Decimal('3.14160')
print(f"approx_equal({val1}, {val2}): {approx_equal(val1, val2)}")
print(f"approx_equal({val1}, {val2}, 0.00001): {approx_equal(val1, val2, Decimal('0.00001'))}")

  1. a ← 10.5, b ← 20.3, c ← 10.5, numbers ← [Decimal('12.5'), Decimal('45.2'), Decimal('23.7'), Decimal('89.1')]

    5# Comparison6a→ 10.5 = Decimal('10.5')7b→ 20.3 = Decimal('20.3')8c→ 10.5 = Decimal('10.5')910print(f"a = {a10.5}")11print(f"b = {b20.3}")12print(f"c = {c10.5}")13print()1415# Equality16print("Equality:")17print(f"a == b: {a10.5 == b20.3}")18print(f"a == c: {a10.5 == c10.5}")19print(f"a != b: {a10.5 != b20.3}")2021# Ordering22print("\nOrdering:")23print(f"a < b: {a10.5 < b20.3}")24print(f"a <= b: {a10.5 <= b20.3}")25print(f"a > b: {a10.5 > b20.3}")26print(f"a >= b: {a10.5 >= b20.3}")2728# compare method29print("\ncompare method:")30print(f"a.compare(b): {a10.5.compare(b20.3)}")  # -1, 0, or 131print(f"b.compare(a): {b20.3.compare(a10.5)}")32print(f"a.compare(c): {a10.5.compare(c10.5)}")3334# compare_signal (raises on NaN)35print("\ncompare_signal:")36print(f"a.compare_signal(b): {a10.5.compare_signal(b20.3)}")3738# max and min39print("\nmax and min:")40print(f"max(a, b): {max(a10.5, b20.3)}")41print(f"min(a, b): {min(a10.5, b20.3)}")4243# Decimal max/min methods44print("\nDecimal max/min methods:")45print(f"a.max(b): {a10.5.max(b20.3)}")46print(f"a.min(b): {a10.5.min(b20.3)}")4748# Find max/min in list49print("\nFind max/min in list:")50numbers→ [Decimal('12.5'), Decimal('45.2'), Decimal('23.7'), Decimal('89.1')] = [Decimal('12.5'), Decimal('45.2'), Decimal('23.7'), Decimal('89.1')]51print(f"Numbers: {numbers[Decimal('12.5'), Decimal('45.2'), Decimal('23.7'), Decimal('89.1')]}")52print(f"Max: {max(numbers[Decimal('12.5'), Decimal('45.2'), Decimal('23.7'), Decimal('89.1')])}")53print(f"Min: {min(numbers[Decimal('12.5'), Decimal('45.2'), Decimal('23.7'), Decimal('89.1')])}")5455# Sort56print("\nSort:")57sorted_nums→ [Decimal('12.5'), Decimal('23.7'), Decimal('45.2'), Decimal('89.1')] = sorted(numbers[Decimal('12.5'), Decimal('45.2'), Decimal('23.7'), Decimal('89.1')])58print(f"Sorted: {sorted_nums[Decimal('12.5'), Decimal('23.7'), Decimal('45.2'), Decimal('89.1')]}")5960# Check if in range61print("\nCheck if in range:")62value→ 15.5 = Decimal('15.5')63lower→ 10 = Decimal('10')64upper→ 20 = Decimal('20')65in_range→ True = lower10 <= value15.5 <= upper2066print(f"{value15.5} in [{lower10}, {upper20}]: {in_rangeTrue}")6768# Zero checks69print("\nZero checks:")70zero→ 0 = Decimal('0')71pos→ 5 = Decimal('5')72neg→ -5 = Decimal('-5')7374print(f"{zero0} == 0: {zero == 0}")75print(f"{pos5} > 0: {pos > 0}")76print(f"{neg-5} < 0: {neg < 0}")7778# is_zero method79print("\nis_zero method:")80print(f"{zero0}.is_zero(): {zero.is_zero()}")81print(f"{pos5}.is_zero(): {pos.is_zero()}")8283# Sign checks84print("\nSign checks:")85print(f"{pos5}.is_signed(): {pos.is_signed()}")86print(f"{neg-5}.is_signed(): {neg.is_signed()}")87print(f"{zero0}.is_signed(): {zero.is_signed()}")8889# is_finite, is_infinite, is_nan90print("\nSpecial value checks:")91finite→ 42.5 = Decimal('42.5')92infinity→ Infinity = Decimal('Infinity')93nan→ NaN = Decimal('NaN')9495print(f"{finite42.5}.is_finite(): {finite.is_finite()}")96print(f"{infinityInfinity}.is_infinite(): {infinity.is_infinite()}")97print(f"{nanNaN}.is_nan(): {nan.is_nan()}")9899# is_normal, is_subnormal100print("\nis_normal:")101normal→ 1.5 = Decimal('1.5')102tiny→ 1E-1000 = Decimal('1e-1000')103print(f"{normal1.5}.is_normal(): {normal.is_normal()}")104print(f"{tiny1E-1000}.is_normal(): {tiny.is_normal()}")105106# compare_total (considers exponent)107print("\ncompare_total (considers exponent):")108d1→ 1.0 = Decimal('1.0')109d2→ 1.00 = Decimal('1.00')110print(f"d1 = {d11.0}, d2 = {d21.00}")111print(f"d1 == d2: {d11.0 == d21.00}")  # True (value equal)112print(f"d1.compare_total(d2): {d11.0.compare_total(d21.00)}")  # -1 (exponents differ)113114# Tolerance comparison (for floats converted to Decimal)115print("\nTolerance comparison:")116def approx_equal(a, b, tolerance=Decimal('0.0001')):117    """Check if two Decimals are approximately equal."""118    return abs(a - b) <= tolerance119120val1→ 3.14159 = Decimal('3.14159')121val2→ 3.14160 = Decimal('3.14160')122print(f"approx_equal({val13.14159}, {val23.14160}): {approx_equal(val1, val2)}")123print(f"approx_equal({val1}, {val2}, 0.00001): {approx_equal(val1, val2, Decimal('0.00001'))}")
    outputa = 10.5
    b = 20.3
    c = 10.5
    Equality:
    a == b: False
    a == c: True
    a != b: True
    
    Ordering:
    a < b: True
    a <= b: True
    a > b: False
    a >= b: False
    
    compare method:
    a.compare(b): -1
    b.compare(a): 1
    a.compare(c): 0
    
    compare_signal:
    a.compare_signal(b): -1
    
    max and min:
    max(a, b): 20.3
    min(a, b): 10.5
    
    Decimal max/min methods:
    a.max(b): 20.3
    a.min(b): 10.5
    
    Find max/min in list:
    Numbers: [Decimal('12.5'), Decimal('45.2'), Decimal('23.7'), Decimal('89.1')]
    Max: 89.1
    Min: 12.5
    
    Sort:
    Sorted: [Decimal('12.5'), Decimal('23.7'), Decimal('45.2'), Decimal('89.1')]
    
    Check if in range:
    15.5 in [10, 20]: True
    
    Zero checks:
    0 == 0: True
    5 > 0: True
    -5 < 0: True
    
    is_zero method:
    0.is_zero(): True
    5.is_zero(): False
    
    Sign checks:
    5.is_signed(): False
    -5.is_signed(): True
    0.is_signed(): False
    
    Special value checks:
    42.5.is_finite(): True
    Infinity.is_infinite(): True
    NaN.is_nan(): True
    
    is_normal:
    1.5.is_normal(): True
    1E-1000.is_normal(): True
    
    compare_total (considers exponent):
    d1 = 1.0, d2 = 1.00
    d1 == d2: True
    d1.compare_total(d2): 1
    
    Tolerance comparison:
  2. def approx_equal(a, b, tolerance=Decimal('0.0001')):

    pass 1 of 2
    115print("\nTolerance comparison:")116def approx_equal(a3.14159, b3.14160, tolerance0.0001=Decimal('0.0001')):117    """Check if two Decimals are approximately equal."""118    return abs(a3.14159 - b3.14160) <= tolerance0.0001
  3. print(f"approx_equal({val1}, {val2}): {approx_equal(val1, val2)}")

    121val2 = Decimal('3.14160')122print(f"approx_equal({val13.14159}, {val23.14160}): {approx_equal(val1, val2)}")123print(f"approx_equal({val13.14159}, {val23.14160}, 0.00001): {approx_equal(val1, val2, Decimal('0.00001'))}")
    outputapprox_equal(3.14159, 3.14160): True
  4. def approx_equal(a, b, tolerance=Decimal('0.0001')):

    pass 2 of 2
    115print("\nTolerance comparison:")116def approx_equal(a3.14159, b3.14160, tolerance0.00001=Decimal('0.0001')):117    """Check if two Decimals are approximately equal."""118    return abs(a3.14159 - b3.14160) <= tolerance0.00001
  5. print(f"approx_equal({val1}, {val2}, 0.00001): {approx_equal(val1, val…

    122print(f"approx_equal({val1}, {val2}): {approx_equal(val1, val2)}")123print(f"approx_equal({val13.14159}, {val23.14160}, 0.00001): {approx_equal(val1, val2, Decimal('0.00001'))}")
    outputapprox_equal(3.14159, 3.14160, 0.00001): True

Exercise: practical.py

Calculate compound interest and format currency values with proper rounding