# How to divide in LaTeX without it rounding or truncating?

I'm working on a diagram and I'm pretty new to LaTeX, so I've decided to try to do it using math instead of statically assigned values. I have come up with the following:

\newcommand\qoffset{14}
\newcommand\smallx{8}
\newcommand\smally{4}
\newcommand\py{\the\numexpr\smally * (\qoffset / (\qoffset - \smallx))}
\the\numexpr\qoffset / (\qoffset - \smallx)


The answer should be 9.3 for \py but the division is rounding (or truncating) and I need decimal point precision. How would I go about doing this?

NOTE: I am not dead set on using \the\numexpr, it's just what I found when trying to figure out how to do math.

\numexpr works only on integers. If you want decimals you have to use \dimexpr (note that you have to add the pt unit to the numerator):

\documentclass{article}
\makeatletter
\def\dimeval#1{\strip@pt\dimexpr#1\relax}
\makeatother
\begin{document}
\newcommand\qoffset{14}
\newcommand\smallx{8}
\newcommand\smally{4}
\dimeval{\qoffset pt / (\qoffset - \smallx)}

\dimeval{\smally pt * (\qoffset / (\qoffset - \smallx))}
\end{document}


which results:

which is correct for the first one, but not as much for the second (it should be 9.33333).

The second one is wrong (depending on your point of view) because \dimexpr only does integer division and multiplication, so (replacing the values) 4pt * ( 14 / ( 14 - 8 ) ) evaluates to 4pt * ( 14 / 6 ) then to 4pt * 2.33333, and 2.33333 truncates to 2 and the result is 8. You can get a bit closer with

\dimeval{\smally pt * \dimeval{\qoffset pt / (\qoffset - \smallx)}}


but a bit wrong is still wrong.

If you want real floating point arithmetics (without having to worry about units), use \fpeval from the xfp package:

\documentclass{article}
\usepackage{xfp}
\begin{document}
\newcommand\qoffset{14}
\newcommand\smallx{8}
\newcommand\smally{4}
\fpeval{\qoffset / (\qoffset - \smallx)}

\fpeval{\smally * (\qoffset / (\qoffset - \smallx))}
\end{document}


which results

As Mico says, you might want rounding. If want for typesetting numbers the best option is the siunitx package:

\documentclass{article}
\usepackage{xfp}
\usepackage{siunitx}
\begin{document}
\num[round-mode=places, round-precision=5]%
{\fpeval{4 * (14 / (14 - 8))}}
\end{document}


but if you want to round for further calculations, then you can use the round function directly (the syntax is round(<num>,<digits>)):

\documentclass{article}
\usepackage{xfp}
\begin{document}
\fpeval{round(  4 * (14 / (14 - 8))  ,5)}
\end{document}


• +1. :-) One could add that if the OP wishes to display the number rounded to, say, 3 digits, he/she could do so by (a) loading the siunitx package and (b) typing \num[round-mode=places, round-precision=3]{\fpeval{\qoffset / (\qoffset - \smallx)}}, i.e., by encasing the result of the calculation in a \num directive.
– Mico
Aug 11, 2020 at 4:05
• \dimexpr is really weird. It will not do what you expect for a / b but it will do for c * a / b. So I usually make a scratch \dimen, write 1pt to it and use the second form to get proper floating point division. Aug 11, 2020 at 20:28

Would you consider using LuaTeX? Then you could evaluate even more complicated expressions:

% gobble ".0" for integers and rounding function
\begingroup
\catcode\%=12
\directlua{
function math.round_int ( x )
return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5)
end
function math.round ( x , n )
return math.round_int ( x*10^n ) / 10^n
end
function gobblezero(x)
local y = math.round ( x , 8 )
if y == math.floor(y) then
return string.format ( "%.0f", y )
else
return math.round(y, 7)
end
end}
\endgroup

\def\fpeval#1{\directlua{tex.print(gobblezero(#1))}}

$$\root 6 \of {64} = \fpeval{64^(1/6)}$$

With rounding:
%
$$1/3 = \fpeval{math.round(1/3, 1)}...$$

\bye


• Nice example! Though I have to say that xfp is a mostly IEEE-754 compliant floating point engine, so \fpeval{64^(1/6)} and \fpeval{round(1/3, 1)} produce the same output as Lua (and it's engine-independent :-) Aug 11, 2020 at 13:41
• You are right of course, but if someone uses LuaTeX he can avoid many lines of code by using the floating point engine from Lua. ;) This should also be faster, I think. Aug 11, 2020 at 15:45
• Indeed, using a built-in floating point engine is a lot faster than the macro emulation. Aug 11, 2020 at 16:44
• Writing such macros is extremly difficult. I wanted to try this as I like programming in TeX, but I gave up soon. See: tex.stackexchange.com/questions/540758/… Aug 11, 2020 at 17:33
• The implementation is indeed extremely complex. The xfp package I mentioned uses the expandable floating point engine from expl3. Take a look at the l3fp` implementation (section 24, around page 700) if you're interested (I tried to understand the implementation, but have failed so far :-) Aug 11, 2020 at 17:44