檢查有效的浮點數

檢查有效的浮點數

我想要執行以下操作:我正在產生一個可以設定為英製或公制單位的報表。所有數值最初均採用公制單位,因此在英制單位的情況下,所有值都應進行轉換。有些值可以是 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

相關內容