Prüfen auf gültige Gleitkommazahlen

Prüfen auf gültige Gleitkommazahlen

Ich möchte Folgendes tun: Ich erstelle einen Bericht, der auf imperiale oder metrische Einheiten eingestellt werden kann. Alle Werte sind ursprünglich in metrischen Einheiten, daher sollten im Fall imperialer Einheiten alle Werte konvertiert werden. Einige Werte können beispielsweise N/A oder ein beliebiger anderer Zeichenfolgenwert sein, falls der Wert nicht anwendbar ist. Das Dokument wird automatisch generiert. Für die Konvertierung verwende ich das fp-Paket, aber die Herausforderung besteht darin, die Eingabe zu überprüfen. Das fp-Paket (und pgfmath) wird natürlich einen Fehler ausgeben, wenn Sie versuchen, mit nicht numerischen Werten zu rechnen. Das ist, was ich derzeit habe (funktioniert nur für ganzzahlige Eingaben)

% 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
}

Mit pgfmath könnte man so etwas machen

\newcommand{\convertmtoin}[2]
{
    \pgfmathfloatparsenumber{#1}
    \pgfmathfloatifflags{\pgfmathresult}{3}{\FPeval{val}{#1*39.3700787} \FPround{\val}{\val}{#2}}{\def\val{#1}} 
}

Ich kann den Fehlerhandler von pgfmath jedoch nicht so einstellen, dass er im Falle einer fehlerhaften Eingabe in pgfmathfloatparsenumber NaN ausgibt.

\pgfkeys{/pgf/fpu/handlers/invalid number={??}{??}}

Vielen Dank für jede Hilfe!

Antwort1

Sie können auch \IfDecimalvon verwendenDas xstringPaket:

Bildbeschreibung hier eingeben

Code:

\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}

Antwort2

AKTUALISIERT, um Negative zu verarbeiten.

Ein Aufruf von \testrealrichtet eine rekursive Schleife ein, die jedes Byte im String überprüft.

Zunächst wird ein führendes Negativzeichen (sofern vorhanden) entfernt, da dies keinen Einfluss darauf hat, ob der Rest der Zeichenfolge eine gültige reelle Zahl ist oder nicht.

Mit dem, was übrig bleibt, geht es wie folgt weiter. Es stellt fest, dass in der Zeichenfolge noch keine Ziffer oder Dezimalstelle gefunden wurde, nimmt jedoch an, dass es sich um eine gültige reelle Zahl handelt.

Beim Durchgehen jedes nachfolgenden Bytes wechselt der Test in den Zustand „fehlgeschlagen“, wenn er eine Nicht-Dezimalzahl oder eine Nicht-Ziffer findet. Der Test schlägt auch fehl, wenn er zwei Dezimalstellen in der Zeichenfolge findet. Aber selbst wenn beide Tests bestanden werden, muss mindestens eine Ziffer gefunden worden sein, damit der Test bestanden wird.

\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} 

Bildbeschreibung hier eingeben

Antwort3

datatoolbietet Bedingungen zum Testen, ob ein Argument numerisch ist oder nicht:

Bildbeschreibung hier eingeben

\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}

Es gibt \DTLisnumericalund \DTLifnumerical. Siehe Abschnitt2.2 ifthen-Bedingungen(S. 16) derdatatoolBenutzerhandbuch.

Antwort4

Ich habe nicht ganz verstanden, was Ihre Absicht ist, aber hier ist ein kurzes Beispiel für die Entwicklung von PGF-Lösungen.

\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}

Dies gibt

NaN

NaN

39.37007

Nanny

verwandte Informationen