Search code examples
pythondecimalcmath

How to increase decimal precision with 'exotic' functions?


I can't figure out how to specify my decimal precision for logs, importing decimal and setting the context does not affect the log functions.

from decimal import *
getcontext().prec = 54

print(Decimal(197)/ Decimal(83))
2.37349397590361445783132530120481927710843373493975904

print(math.log(Decimal(197)))
5.2832037287379885

I would like to set a high precision for functions other than fractions. Python 3 btw.


Solution

  • Possible solutions:

    String formatting:

    x = 4567.09710599898797936589076897
    y = 2445.89790870380808990080797897
    

    Lengthen:

    print(f'{(x/y):.054f}')
    >>> 1.867247643389702504990168563381303101778030395507812500
    
    calculation = math.log(197)
    print(f'{calculation:.050f}')
    >>> 5.28320372873798849155946300015784800052642822265625
    

    Shorten:

    print(f'{(x/y):.02f}')
    >>> 1.87
    

    numpy:

    Shorten:

    print(np.round(x/y, 2))
    >>> 1.87
    

    Lengthen:

    • numpy does not extend the precision shown, beyond what's shown by python.
    print(np.around(x/y, 54))
    >>> 1.8672476433897025
    
    print(x/y)
    >>> 1.8672476433897025
    

    decimal Module:

    Example from the question:

    print(math.log(197))
    >>> 5.2832037287379885
    
    print(math.log(Decimal(197.0)))
    >>> 5.2832037287379885
    
    print(Decimal(math.log(197)))
    >>> 5.28320372873798849155946300015784800052642822265625
    
    print(Decimal(197).ln())
    >>> 5.283203728737988506779797329
    
    print(f'{math.log(197):.050f}')
    >>> 5.28320372873798849155946300015784800052642822265625
    

    Notes:

    • Either method can be used to format the number to the required decimal place, prior to writing into a log.
    • Caveat: due to the way numbers are represented in computers, I'm doubtful if increasing the number of decimal places shown, increases the precision.
    • Using f-strings provided the same final output precision as using the decimal module.