我想做以下事情:我正在生成一份报告,可以将其设置为英制或公制单位。所有值最初都是公制单位,因此如果是英制单位,则所有值都应转换。如果值不适用,则某些值可以是 N/A 或任何其他字符串值。文档是自动生成的。对于转换,我使用的是 fp 包,但挑战在于检查输入。如果您尝试使用非数值进行数学运算,fp 包(和 pgfmath)当然会出错。这是我目前拥有的(仅适用于整数输入)
% Convert meters to inches
\newcommand{\convertmtoin}[2]
{
\if!\ifnum9<1#1!\else_\fi
\FPeval{val}{#1*39.3700787} \FPround{\val}{\val}{#2}
\else
\def\val{#1}
\fi
}
使用 pgfmath 可以做这样的事情
\newcommand{\convertmtoin}[2]
{
\pgfmathfloatparsenumber{#1}
\pgfmathfloatifflags{\pgfmathresult}{3}{\FPeval{val}{#1*39.3700787} \FPround{\val}{\val}{#2}}{\def\val{#1}}
}
但是,我无法将 pgfmath 的错误处理程序设置为在 pgfmathfloatparsenumber 输入错误的情况下输出 NaN
\pgfkeys{/pgf/fpu/handlers/invalid number={??}{??}}
谢谢你的帮助!
答案1
您还可以\IfDecimal
使用包裹xstring
:
代码:
\documentclass{article}
\usepackage{xstring}
\newcommand*{\CheckIfNumerical}[1]{%
\IfDecimal{#1}{%
``#1" is a number.%
}{%
``#1" is NOT a number.%
}%
}%
\begin{document}
\par\CheckIfNumerical{7}
\par\CheckIfNumerical{3.14}
\par\CheckIfNumerical{NaN}
\par\CheckIfNumerical{7. 0}
\par\CheckIfNumerical{7.0X09}
\end{document}
答案2
已更新以处理负面情况。
调用\testreal
设置一个递归循环来检查字符串中的每个字节。
首先,如果存在前导负数,它会将其删除,因为这不会影响字符串的其余部分是否是有效的实数。
对于剩下的内容,它是这样进行的。它注意到在字符串中还没有找到数字或小数点,但假设它是一个有效的实数。
测试会检查每个连续的字节,如果发现非小数、非数字,则切换到“失败”状态。如果在字符串中发现两个小数点,测试也会失败。但即使这两个测试都通过,也必须至少找到一个数字,才能通过测试。
\documentclass[]{article}
\def\testreal#1{\def\founddigit{F}\def\itsanumber{T}\def\fndpt{F}%
\edef\tmp{\testleadneg#1\relax}%
\expandafter\testrealhelper\tmp\relax%
\if T\founddigit\itsanumber\else F\fi}
\def\testrealhelper#1#2\relax{%
\if.#1\if T\fndpt\def\itsanumber{F}\else\def\fndpt{T}\fi\else
\if1#1\FD\else
\if2#1\FD\else
\if3#1\FD\else
\if4#1\FD\else
\if5#1\FD\else
\if6#1\FD\else
\if7#1\FD\else
\if8#1\FD\else
\if9#1\FD\else
\if0#1\FD\else\def\itsanumber{F}%
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
\if\relax#2\else\testrealhelper#2\relax\fi}
\def\testleadneg#1#2\relax{\if-#1#2\else#1#2\fi}
\def\FD{\def\founddigit{T}}
\begin{document}
\testreal{just} \testreal{-just}
\testreal{123John} \testreal{-123John}
\testreal{324.56} \testreal{-324.56}
\testreal{.} \testreal{-.}
\testreal{23.4.56} \testreal{-23.4.56}
\testreal{346} \testreal{-346}
\end{document}
答案3
datatool
提供测试参数是否为数字的条件:
\documentclass{article}
\usepackage{datatool}% http://ctan.org/pkg/datatool
\newcommand{\testreal}[1]{\ifthenelse{\DTLisnumerical{#1}}{T}{F}}
\begin{document}
\testreal{just}
\testreal{123John}
\testreal{324.56}
\testreal{.}
\testreal{23.4.56}
\testreal{346}
\end{document}
有\DTLisnumerical
和\DTLifnumerical
。请参阅第节2.2 ifthen 条件语句(第 16 页)datatool
用户指南。
答案4
我不太明白你的意图,但这里有一个提出 PGF 解决方案的简单示例。
\documentclass[]{article}
\usepackage{pgf}
\usepgflibrary{fpu}
\pgfmathdeclarefunction{m2in}{1}{%
\begingroup
\pgfkeys{/pgf/fpu}
\pgfmathfloatparsenumber{#1}
\pgfmathfloatifflags{\pgfmathresult}{3}{%True Not a number
\def\pgfmathresult{3Y0.0e0]}%
\pgfmathfloattofixed{\pgfmathresult}%
}{% False it is a number including inf
\pgfmathfloatparsenumber{#1}%
\pgfmathfloatmultiplyfixed{\pgfmathresult}{39.3700787}%
\pgfmathfloattofixed{\pgfmathresult}%
}
\pgfmathsmuggle\pgfmathresult%
\endgroup
}%
\pgfkeys{/pgf/fpu/handlers/invalid number/.code={%
\pgfmathfloatparsenumber{3Y0.0e0]}%
}
}
\begin{document}
\pgfmathfloatparsenumber{435...}% NaN
\pgfmathprintnumber[fixed]{\pgfmathresult}
\pgfmathfloatparsenumber{la la laa}% NaN
\pgfmathprintnumber[fixed]{\pgfmathresult}
\pgfmathparse{m2in(1.000)}\pgfmathprintnumber[fixed,precision=5]\pgfmathresult
\pgfmathparse{m2in(4..4)}\pgfmathresult
\end{document}
这将使
钠
钠
39.37007
南