\IfDecimal 返回大数

\IfDecimal 返回大数

\IfDecimal 返回一个错误数字,该数字过大且小数点很大。我的目标是如果数字为数字,则打印四舍五入到位数的百分比,否则只打印参数的值。有没有办法绕过这个大小限制,或者有没有其他方法可以解决这个问题,因为我还不知道我是否有可解析的数字?\SomePerc 是一个简化的宏,我正在尝试使用。SomePerc 的输入要么是浮点数,要么是“-”(作为破折号而不是负数)

\documentclass[]{article}
\usepackage{siunitx}
\usepackage{xstring}

\newcommand\SomePerc[1]{
    \IfDecimal{#1}
    {\qty[  exponent-mode = fixed,
        fixed-exponent = 0,
        drop-exponent=true, 
        drop-zero-decimal=true,
        round-mode=places,
        round-precision =2]{#1e2}{\percent}
    }
    {#1}
}

\begin{document}

\IfDecimal{0.05479140921}{true}{false}
\IfDecimal{0.0547914092}{true}{false} 

\num{0.054791409210}

\SomePerc{0.05479140921}
\SomePerc{0.0547914092}

\end{document}

latex 编译器说:

Number too big. \IfDecimal{0.05479140921}
Number too big. \SomePerc{0.05479140921}

答案1

以下定义了\ifdecimal一个可扩展、快速的测试,适用于任意大的数字和位置。它既适用于,.作为小数分隔符,也适用于任意多个符号。所有至少有一位数字、最多一位小数分隔符且没有空格的数都被视为十进制数。输入被完全扩展然后字符串化,其结果必须符合上述规则。

\documentclass{article}

\makeatletter
% needed to get a space inside of a definition
\newcommand\exparg@o[2]{\expanded{\unexpanded{#1}\expandafter}\expandafter{#2}}

% the front facing macro
\newcommand\ifdecimal[1]
  {%
    \expandafter\ifdecimal@space\detokenize\expanded{{#1}}\STOP
    \ifdecimal@true
  }

% true and false branching
\let\ifdecimal@true\@firstoftwo
\long\def\ifdecimal@false#1\ifdecimal@true#2#3{#3}

% check has no spaces
\exparg@o{\def\ifdecimal@space#1\STOP}%
  {%
    \@firstofone{\ifdecimal@space@#1\STOP\ifdecimal@false} \STOP % <- space
    \ifdecimal@sign#1\MARK,\MARK
  }
\def\ifdecimal@space@#1 #2\STOP{}

% strip leading signs
\def\ifdecimal@sign#1%
  {%
    \ifdecimal@sign@#1-\ifdecimal@sign@true+#1\ifdecimal@sign@true
      +-\ifdecimal@dot#1%
  }
\def\ifdecimal@sign@#1+-{}
\def\ifdecimal@sign@true#1+-\ifdecimal@dot#2{\ifdecimal@sign}

% turn one , into a . and then remove one decimal marker
\def\ifdecimal@dot#1,{\ifdecimal@dot@#1.}
\def\ifdecimal@dot@#1.{\ifdecimal@healmark\ifdecimal@empty#1}
\def\ifdecimal@healmark#1\MARK#2\MARK{#1\STOP}

% check is non-empty
\def\ifdecimal@empty#1\STOP
  {%
    \ifdecimal@empty@\MARK#1\STOP\ifdecimal@false\MARK\STOP
    % the {0 \ifdecimal@done} works as the right delimiter to the input argument
    \ifdecimal@digits#1{0 \ifdecimal@done}%
  }
\def\ifdecimal@empty@#1\MARK\STOP{}

% check only digits left
\def\ifdecimal@digits#1%
  {%
    \ifnum9<1#1
    \else
      \expandafter\ifdecimal@false
    \fi
    \ifdecimal@digits
  }
\def\ifdecimal@done#1\ifdecimal@digits{\fi}
\let\MARK\relax
\let\STOP\relax
\makeatother

% simple tests whether the macro works
\newcommand\ASSERT[2]
  {%
    \begingroup
      \edef\tmpa{#2}%
      \def\tmpb{#1}%
      \expandafter
    \endgroup
    \ifx\tmpa\tmpb
    \else
      \GenericError{}{Assertion failed for \detokenize{#2}}{}{}%
    \fi
  }

\ASSERT{true}{\ifdecimal{0.}{true}{false}}
\ASSERT{true}{\ifdecimal{.0}{true}{false}}
\ASSERT{true}{\ifdecimal{0.0}{true}{false}}
\ASSERT{true}{\ifdecimal{00}{true}{false}}
\ASSERT{true}{\ifdecimal{+-+-+-+-00}{true}{false}}
\ASSERT{false}{\ifdecimal{.}{true}{false}}
\ASSERT{false}{\ifdecimal{+}{true}{false}}
\ASSERT{false}{\ifdecimal{-}{true}{false}}
\ASSERT{false}{\ifdecimal{+-}{true}{false}}
\ASSERT{false}{\ifdecimal{+-.}{true}{false}}
\ASSERT{false}{\ifdecimal{0+}{true}{false}}
\ASSERT{false}{\ifdecimal{0.0.0}{true}{false}}
\ASSERT{false}{\ifdecimal{a}{true}{false}}

\newcommand\five{5}
\ASSERT{true}{\ifdecimal{\five}{true}{false}}
\ASSERT{true}{\ifdecimal{\five .\five}{true}{false}}
\ASSERT{true}{\ifdecimal{\empty .\five}{true}{false}}
\ASSERT{false}{\ifdecimal{\five .\relax}{true}{false}}

\stop

相关内容