Comprobando el número de punto flotante válido

Comprobando el número de punto flotante válido

Quiero hacer lo siguiente: estoy generando un informe que se puede configurar en unidades imperiales o métricas. Todos los valores están originalmente en unidades métricas, por lo que en el caso de unidades imperiales se deben convertir todos los valores. Algunos valores pueden ser N/A o cualquier otro valor de cadena, en caso de que el valor no sea aplicable. El documento se genera automáticamente. Para la conversión estoy usando el paquete fp, pero el desafío es verificar la entrada. El paquete fp (y pgfmath), por supuesto, se equivocará si intenta hacer cálculos con valores no numéricos. Esto es lo que tengo actualmente (sólo funciona para entrada de números enteros)

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

Usando pgfmath se podría hacer algo como esto

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

Pero no puedo configurar el controlador de errores de pgfmath para que genere NaN en el caso de una entrada errónea en pgfmathfloatparsenumber.

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

¡Gracias por cualquier ayuda!

Respuesta1

También puedes utilizar \IfDecimaldesdeel xstringpaquete:

ingrese la descripción de la imagen aquí

Código:

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

Respuesta2

ACTUALIZADO para manejar los aspectos negativos.

Una llamada a \testrealconfigura un bucle recursivo que comprueba cada byte de la cadena.

Primero, elimina un negativo inicial, si existe, ya que eso no afectará si el resto de la cadena es o no un número real válido.

Con lo que queda, así es como se procede. Observa que aún no se ha encontrado ningún dígito ni punto decimal en la cadena, pero supone que es un número real válido.

Al revisar cada byte sucesivo, la prueba cambiará al estado "fallido" si localiza un valor que no sea decimal ni dígito. La prueba también fallará si encuentra dos puntos decimales en la cadena. Pero incluso si se pasan ambas pruebas, debe haber encontrado al menos un dígito para pasar la prueba.

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

ingrese la descripción de la imagen aquí

Respuesta3

datatoolproporciona condicionales para probar si un argumento es numérico o no:

ingrese la descripción de la imagen aquí

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

Hay \DTLisnumericaly \DTLifnumerical. Mira la sección2.2 condicionales si entonces(pág. 16) de ladatatoolguía del usuario.

Respuesta4

No entendí muy bien cuál es su intención, pero aquí hay un ejemplo rápido para encontrar soluciones 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}

esto le dará

Yaya

Yaya

39.37007

yaya

información relacionada