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 \IfDecimal
von verwendenDas xstring
Paket:
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 \testreal
richtet 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}
Antwort3
datatool
bietet Bedingungen zum Testen, ob ein Argument numerisch ist oder nicht:
\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 \DTLisnumerical
und \DTLifnumerical
. Siehe Abschnitt2.2 ifthen-Bedingungen(S. 16) derdatatool
Benutzerhandbuch.
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