1

Converting a decimal value to string causes it to lose precision or change value, see the following example:

from decimal import Decimal, getcontext

# Create a string value of a decimal
value = str(Decimal(97.17312522036036245646))

print(value) # -> 97.17312522036036170902661979198455810546875

# Ideally I would like to get '97.17312522036036245646' or '97.1731252203603624564600000' # based on the precision that I set.
Marc
  • 379
  • 4
  • 8
  • Does this answer your question? [Setting precision in Decimal class Python](https://stackoverflow.com/questions/27638005/setting-precision-in-decimal-class-python) – Kroshtan Aug 21 '23 at 13:37
  • 10
    You lost all hope of a precise result the moment you wrote `97.17312522036036245646` as a float value. You need to pass that to `Decimal()` as a string. – jasonharper Aug 21 '23 at 13:39
  • Does this answer your question? [Python "decimal" package gives wrong results](https://stackoverflow.com/questions/62927128/python-decimal-package-gives-wrong-results) or [Decimal module in Python inaccurate](https://stackoverflow.com/questions/71661286/decimal-module-in-python-inaccurate) – Abdul Aziz Barkat Aug 21 '23 at 13:48

2 Answers2

1

One solution is to input the decimal number as a string:

from decimal import Decimal

value = str(Decimal("97.17312522036036245646"))

print(value)

The output is 97.17312522036036245646

Plonetheus
  • 704
  • 3
  • 11
-2

Another approach is to utilize f-strings and their ability to manipulate strings. First I present the method, then walk through it

def format_float_string(string_value: str, num_decimals: int) -> str:
    # Split the input string into its integer and decimal parts
    number, decimal = string_value.split('.')
    
    # Format the integer part
    formatted_integer = f"{int(number):d}"
    
    # Format the decimal part with the specified number of decimal places
    formatted_decimal = f"{int(decimal[:num_decimals]):0<{num_decimals}}"
    
    return f"{formatted_integer}.{formatted_decimal}"

# Test the function with an example value
test_string = "97.17312522036036245646"
test_decimals = 5
format_float_string(test_string, test_decimals) ----> '97.17312'
format_float_string(test_string, 30) ----> '97.173125220360362456460000000000'

Knowing a string representation of a float we can split the number in into the integer and fractional bits. Only the fractional bit needs to be formatted, where we can use num_decimals to cut off at the the desired digit by indexing the string. The of the number of decimals are higher than the actual string representation it will be filled with zeros.