views:

38

answers:

2

I'm trying to implement decimal arithmetic in (La)TeX. I'm trying to use dimens to store the values. I want the arithmetic to be exact to some (fixed) number of decimal places. If I use 1pt as my base unit, then this fails, because \divide rounds down, so 1pt / 10 gives 0.09999pt. If I use something like 1000sp as my base unit, then I get working fixed point arithmetic with 3 decimal places, but I can't figure out an easy way to format the numbers. If I try to convert them to pt, so I can use TeX's display mechanism, I have the same problem with \divide.

How do I fix this problem, or work around it?

+1  A: 

I would represent all the values as integers and scale them appropriately. For example, when you need three decimal digits, 0.124 would be represented as 124. This is nice because addition and subtraction are trivial. When multiplying two numbers a and b, you would have to divide the result by 1000 to get the proper representation. Dividing works by multiplying the result with 1000.

You still have to get the rounding issues correct, but this isn't very difficult. At least if you don't get near the maximum representable integer (I don't remember if it's 2^31-1 or 2^30-1).

Here is some code:

\def\fixadd#1#2#3{%
  #1=#2\relax
  \advance #1 by #3\relax
}
\def\fixsub#1#2#3{%
  #1=#2\relax
  #1=-#1\relax
  \advance #1 by #3\relax
  #1=-#1\relax
}
\def\fixmul#1#2#3{%
  #1=#2\relax
  \multiply #1 by #3\relax
  \divide #1 by 1000\relax
}
\def\fixdiv#1#2#3{%
  #1=#2\relax
  \divide #1 by #3\relax
  \multiply #1 by 1000\relax
}

\newcount\numa
\newcount\numb
\newcount\numc

\numa=1414
\numb=2828
\fixmul\numc\numa\numb
\the\numc
\bye

The operations are modeled after a three register machine, where the first is the destination and the other two are the operands. The rounding after the multiplication and division, including corner cases for very large or very small numbers are left as an exercise to you.

Roland Illig
+2  A: 

The fp package provides fixed point arithmetic for LaTeX. The LaTeX3 Project are currently implementing something similar as part of the expl3 bundle. The code is currently not on CTAN, but can be grabbed from the SVN (or will appear when the next update from the SVN to CTAN takes place).

Joseph Wright
I think we'll be sending the LaTeX3 implementation (as it stands) to CTAN this week, so it will be in TeX Live 2010
Joseph Wright