Don't use string manipulation to produce rational numbers.

This commit is contained in:
Chris Berkhout 2021-05-31 17:00:02 +02:00
parent 9996354108
commit 303f5d379a

View file

@ -3,6 +3,7 @@ import logging
import re import re
from datetime import datetime from datetime import datetime
from importlib.resources import read_text from importlib.resources import read_text
from decimal import Decimal
from pricehist import __version__ from pricehist import __version__
from pricehist.format import Format from pricehist.format import Format
@ -44,7 +45,7 @@ class GnuCashSQL(BaseOutput):
) )
guid = m.hexdigest()[0:32] guid = m.hexdigest()[0:32]
value_num, value_denom = self._fractional(price.amount) value_num, value_denom = self._rational(price.amount)
v = ( v = (
"(" "("
+ ", ".join( + ", ".join(
@ -103,7 +104,15 @@ class GnuCashSQL(BaseOutput):
quoted = f"'{escaped}'" quoted = f"'{escaped}'"
return quoted return quoted
def _fractional(self, number): def _rational(self, number: Decimal) -> (str, str):
numerator = str(number).replace(".", "") tup = number.as_tuple()
denom = 10 ** len(f"{number}.".split(".")[1]) sign = "-" if tup.sign == 1 else ""
if tup.exponent > 0:
numerator = (
sign + "".join([str(d) for d in tup.digits]) + ("0" * tup.exponent)
)
denom = str(1)
else:
numerator = sign + "".join([str(d) for d in tup.digits])
denom = str(10 ** -tup.exponent)
return (numerator, denom) return (numerator, denom)