Automatically add fractions and reduce the result (if neccessary)
2020-04-14: Updated to properly output case when denominator is 1.
Using How to create a random math problem in LaTeX?, the link Cramdir pointed out, we can adapt two of the solutions there to do this. One uses Euclid's algorithm, and one uses tkz-fct
.
In order to be able to package both of these solutions into a macro we need to use pgfmathtruncatemacro
to ensure we are working with integers as \pgfmathsetmacro
is always a decimal value. Both these produce identical results.
Here is the MWE using Euclid's algorithm:
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\makeatletter
% Use Euclid's Algorithm to find the greatest
% common divisor of two integers.
\def\gcd#1#2{{% #1 = a, #2 = b
\ifnum#2=0 \edef\next{#1}\else
\@tempcnta=#1 \@tempcntb=#2 \divide\@tempcnta by\@tempcntb
\multiply\@tempcnta by\@tempcntb % q*b
\@tempcntb=#1
\advance\@tempcntb by-\@tempcnta % remainder in \@tempcntb
\ifnum\@tempcntb=0
\@tempcnta=#2
\ifnum\@tempcnta < 0 \@tempcnta=-\@tempcnta\fi
\xdef\gcd@next{\noexpand%
\def\noexpand\thegcd{\the\@tempcnta}}%
\else
\xdef\gcd@next{\noexpand\gcd{#2}{\the\@tempcntb}}%
\fi
\fi}\gcd@next
}
\newcommand\reduceFrac[2]
{%
\gcd{#1}{#2}{\@tempcnta=#1 \divide\@tempcnta by\thegcd
\@tempcntb=#2 \divide\@tempcntb by\thegcd
\ifnum\@tempcntb<0\relax
\@tempcntb=-\@tempcntb
\@tempcnta=-\@tempcnta
\fi
\xdef\rfNumer{\the\@tempcnta}
\xdef\rfDenom{\the\@tempcntb}}%
}
\makeatother
\newcommand*{\fracReduced}[2]{%
\reduceFrac{#1}{#2}%
\ensuremath{%
\ifnum\rfDenom=1
\rfNumer
\else
\frac{\rfNumer}{\rfDenom}%
\fi
}%
}%
\newcommand{\addfraction}[4]{% 1N, 1D, 2N, 2D
\pgfmathsetmacro{\newnumerator}{#1*#4+#3*#2}
\pgfmathsetmacro{\newdenominator}{#4*#2}
\pgfmathtruncatemacro{\newnumeratorTrunc}{\newnumerator}
\pgfmathtruncatemacro{\newdenominatorTrunc}{\newdenominator}
\pgfkeys{/pgf/number format/.cd,int detect,precision=2}
\[ \frac{#1}{#2} + \frac{#3}{#4}
= \frac{\pgfmathprintnumber{\newnumerator}}{\pgfmathprintnumber{\newdenominator}}
= \fracReduced{\newnumeratorTrunc}{\newdenominatorTrunc}
\]
}
\begin{document}
\addfraction{3}{4}{1}{2}
\addfraction{3}{4}{5}{4}
\end{document}
And here is the one using tikz-fct
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usepackage{tkz-fct}
\newcommand*{\fracReducedTkz}[2]{%
\tkzReducFrac{#1}{#2}
\ensuremath{
\ifnum\tkzMathSecondResult=1
\tkzMathFirstResult
\else
\frac{\tkzMathFirstResult}{\tkzMathSecondResult}
\fi
}
}
\newcommand{\addfraction}[4]{% 1N, 1D, 2N, 2D
\pgfmathsetmacro{\newnumerator}{#1*#4+#3*#2}
\pgfmathsetmacro{\newdenominator}{#4*#2}
\pgfmathtruncatemacro{\newnumeratorTrunc}{\newnumerator}
\pgfmathtruncatemacro{\newdenominatorTrunc}{\newdenominator}
\pgfkeys{/pgf/number format/.cd,int detect,precision=2}
\[ \frac{#1}{#2} + \frac{#3}{#4}
= \frac{\pgfmathprintnumber{\newnumerator}}{\pgfmathprintnumber{\newdenominator}}
= \fracReducedTkz{\newnumeratorTrunc}{\newdenominatorTrunc}
\]
}
\begin{document}
\addfraction{3}{4}{1}{2}
\addfraction{3}{4}{5}{4}
\end{document}
The addfraction
commands are identical, except the last line calls a different macro in the two examples.
Here's a LuaTeX solution for fun, in case anyone is interested. This solutions deals with negative cases and division by zero, although it need to be enclosed by $...$. Further tuning can be done with \ifmmode
, though.
%!TEX program = lualatex
\documentclass{standalone}
\usepackage{luacode}
\usepackage{amsmath}
\begin{luacode*}
function gcd(a,b)
if b ~= 0 then
return gcd(b, a % b)
else
return math.abs(a)
end
end
function sgn(a)
if a == 0 then
return 0
else
return a/math.abs(a)
end
end
function fractionadd(a,b,c,d)
local first = a*d + b*c
local second = b*d
frac = first/second
local abs = math.abs
local afirst = abs(first)
local asecond = abs(second)
if second == 0 then
return [[\text{Impossible to divide by zero}]]
elseif gcd(afirst,asecond) == asecond then
return math.floor(sgn(frac)*afirst/(gcd(afirst,asecond)))
else
return [[\frac{]]..math.floor(sgn(frac)*(afirst/gcd(afirst,asecond)))..[[}{]]..math.floor(asecond/gcd(afirst,asecond))..[[}]]
end
end
\end{luacode*}
\newcommand{\fractionadd}[4]{\directlua{tex.print(fractionadd(#1,#2,#3,#4))}}
\begin{document}
$\fractionadd{8}{2}{9}{3}$,
$\fractionadd{1}{2}{1}{3}$,
$\fractionadd{1}{2}{-1}{3}$.
$\fractionadd{-4}{3}{-2}{3}$,
$\fractionadd{4}{-3}{-10}{6}$,
$\fractionadd{-4}{0}{-2}{3}$,
$\fractionadd{1}{5}{-2}{11}$
\end{document}