2

How to use large decimal numbers with fixed precision, like money amount, in emacs lisp? For example, I'm writing a function that takes amount of money as a parameter. When I pass large float like 999999999999999.01 it looses precision and becomes 999999999999999.0. I didn't find fixed type in manual. My workarounds are:

  1. Pass two integers separately, integer part and fraction part - like dollars and cents
  2. Pass amount as string and parse it to two integers,

but both of this approaches will be less convenient for users.

  • 1
    You could use a single integer and then divide it by your fixed number whenever you need to display it. From what I recall, elisp lacks proper bit shifting, so "proper" fixed point numbers can only be approximated with multiplication and division. – DoMiNeLa10 Nov 19 '18 at 19:22
4

You could use the fractional representation of numbers from calc.

I am not sure why you think that passing the amount as string is inconvenient for the user.

I would pass that input to calc and adapt the precision to the length of the string.

Example:

(calc-frac-mode 1)
(setq str "999999999999999.01")
(setq var-x (calc-eval (list (format "pfrac(%s)" str) 'calc-internal-prec (length str)) 'raw))
(setq var-y (calc-eval "pfrac(1.01)" 'raw))
(setq var-z (math-add var-x var-y))
(calc-eval (list "pfloat($)" 'calc-internal-prec (calc-eval "floor(log10(abs($))+3)" 'raw var-z)) nil var-z)

The result of that elisp segment is 1000000000000000.02.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.