I am working with a library that uses int
for representing money amounts. For example, the following is what this looks like:
599
--> $5.99
500
--> $5.00
5
--> $0.05
0
--> $0.00
-599
--> $-5.99
I wrote the following function which does an exact float conversion without causing floating point errors, but what I am wondering is if I am approaching this the wrong way or if there is a much cleaner solution.
def money_int_to_float(value: int) -> float:
neg: str = '-' if value < 0 else ''
value = abs(value)
cents: int = value % 100
remaining: int = value - cents
dollars: int = int(str(remaining).removesuffix('00'))
return float(f'{neg}{dollars}.{str(cents).zfill(2)}')
My reasoning for wanting an exact float conversion is that when dealing with money you can never be too careful with floats.
CodePudding user response:
divmod
sounds like something you should know about:
def money_int_to_str(value: int) -> str:
sign = '-' if value < 0 else ''
dollars, cents = divmod(abs(value), 100)
return f'${sign}{dollars}.{cents:02}'
the reason for staying away from floats would be that, e.g., money_int_to_float(123456789123456789)
won't give you 89 cents from any implementation – there isn't enough precision in a float to store it.
CodePudding user response:
Thanks to @Samwise's comment, I have found a clean solution to this question. Using the Decimal class we can rewrite the function as follows:
from decimal import Decimal
def money_int_to_float(value: int) -> float:
return float(Decimal(value).quantize(Decimal('0.00')).shift(-2))