我正在 LaTeX 中创建发票,并且我输入了工作时间作为小数(例如,1、1.5、0.75、2.25),但我想将这些小数显示为分数(1、1½、¾、2¼)。
(我之所以将工作时间输入为小数,是为了能够使用fp 封装类似于这个答案)
为了提供一些背景信息,下面是我创建的包含工作小时数的宏的概要:
\lineitem{DATE}{HOURS}{RATE}{PROJECT}{DESCRIPTION}
我想到的转换非常简单:
\documentclass{article}
\usepackage{xfrac}
\begin{document}
\begin{tabular}{r @{} l | r @{\hspace{0.1em}} l}
\multicolumn{2}{c}{Given...} & \multicolumn{2}{c}{Output} \\
\hline
1 & & 1 & \\
1 & .5 & 1 & \sfrac{1}{2} \\
0 & .75 & \sfrac{3}{4} & \\
2 & .25 & 2 & \sfrac{1}{4} \\
\end{tabular}
\end{document}
(我并不是\sfrac
因为显示分数而结婚的,这只是我接触到的第一个包)
有没有现成的软件包可以满足我的要求?如果没有,有人能给我一些建议,告诉我如何实现自己的转换/显示逻辑吗?
答案1
改编自自动添加分数并减少结果(如有必要)产量:
笔记:
\hphantom
在您的实际使用案例中,应该注释掉此行。添加它是为了在 TeX.SE 上发布时产生更好的输出。- 这可能不会为所有可能的小数产生理想的结果,但对于所请求的小数确实有效。
- 对于
HH:MM
格式,我使用了包裹xstring
用于字符串比较,因为我更喜欢它的格式,但如果需要的话可能不用这个包也可以。
代码:
\documentclass{article}
\usepackage{tikz}
\usepackage{xfrac}
\usepackage{xstring}
\makeatletter
\newcommand*{\@PositionOfColon}{}%
\newcommand{\IfStrContains}[4]{%
\StrPosition{#1}{#2}[\@PositionOfColon]% Record position in \@PositionOfColon
\IfEq{\@PositionOfColon}{0}%
{#4}% StrPosition=0 => Did not find the target string
{#3}% StrPosition>0 => Found the target string
}%
% 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
}
%% Adapted from https://tex.stackexchange.com/questions/28628/automatically-add-fractions-and-reduce-the-result-if-neccessary
\newcommand*{\rfNumer}{}%
\newcommand*{\rfDenom}{}%
\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{\sfrac{\rfNumer}{\rfDenom}}}%
\newcommand*{\TempNumerator}{}%
\newcommand*{\TempDenominator}{}%
\newcommand*{\DecimalToFrac}[1]{%
\IfStrContains{#1}{:}{%
\StrBefore{#1}{:}[\WholePortion]%
\StrBehind{#1}{:}[\TempNumerator]%
\def\TempDenominator{60}%
}{%
\pgfmathtruncatemacro{\WholePortion}{int(#1)}%
\pgfmathtruncatemacro{\TempNumerator}{100*(#1-\WholePortion)}%
\def\TempDenominator{100}%
}%
#1 =
\ifnum\WholePortion > 0\relax%
\WholePortion%
\else
\hphantom{0}% Just for nicer output of MWE. Should be deleted in actual use
\fi
\fracReduced{\TempNumerator}{\TempDenominator}%
}%
\begin{document}
Using decimals:
\DecimalToFrac{0.75},
\quad
\DecimalToFrac{0.50},
\quad
\DecimalToFrac{0.25}.
\DecimalToFrac{2.75},
\quad
\DecimalToFrac{1.50},
\quad
\DecimalToFrac{3.25}.
\bigskip
Using \texttt{HH:MM} format:
\DecimalToFrac{0:45},
\quad
\DecimalToFrac{0:30},
\quad
\DecimalToFrac{0:15},
\DecimalToFrac{0:20},
\quad
\DecimalToFrac{0:10},
\quad
\DecimalToFrac{0:05}.
\medskip
\DecimalToFrac{2:45},
\quad
\DecimalToFrac{1:15},
\quad
\DecimalToFrac{3:10}.
\DecimalToFrac{2:20},
\quad
\DecimalToFrac{1:10},
\quad
\DecimalToFrac{3:05}.
\end{document}
答案2
tikz
提供以下类型的格式:
\documentclass{article}
\usepackage{tikz,xfrac}
\usetikzlibrary{fpu}
\newcommand{\dectofrac}[1]{\begingroup%
\pgfkeys{/pgf/number format/frac}% Format as fraction
\let\frac\sfrac% Let \frac act like \sfrac
\pgfmathprintnumber{#1}\endgroup}
\pagestyle{empty}
\begin{document}
\begin{tabular}{r @{} l | r @{\hspace{0.1em}} l}
\multicolumn{2}{c}{Given...} & \multicolumn{2}{c}{Output} \\
\hline
1& & 1& \\
1&.5 & 1&\dectofrac{0.5} \\
0&.75 & &\dectofrac{0.75} \\
2&.25 & 2&\dectofrac{0.25}
\end{tabular}
\end{document}