TikZ / pgfmath:如果不是数字,则 pgfmathprintnumber

TikZ / pgfmath:如果不是数字,则 pgfmathprintnumber

在此处输入图片描述

我需要一个功能

1) x=-1 ---> ERROR 
2) x < 0.01 --> 1000*x 
3) x --> x else 

问题:结果应该出现在 和 中\pgfmathprintnumber,但在 的情况下会崩溃1),因为单词 'ERROR' 不是数字。

我能做什么?

顺便提一句:我在主文档中使用 pgfmath 写了很多内容,并且想坚持使用它,而不是在这里使用完全不同的东西。

\documentclass[border=5mm, varwidth]{standalone}
\usepackage{tikz}
\begin{document}
\def\x{5} % works


\pgfmathdeclarefunction{Test}{1}{%%
\pgfmathparse{#1==-1}%
\ifnum\pgfmathresult=1 \pgfmathparse{"ERROR"} \else% 
  \pgfmathparse{#1<0.01}% 
   \ifnum\pgfmathresult=1%
    \pgfmathparse{#1*1000}%
    \else \pgfmathparse{#1}%
    \fi%
\fi}%%

123: \pgfmathparse{Test(123)}
 \pgfmathprintnumber[precision=2]{\pgfmathresult} 
~pgfmathprintnumber works \\

0.0001: \pgfmathparse{Test(0.0001)} 
\pgfmathresult ~works but strange result  \\
\pgfmathprintnumber[precision=2]{\pgfmathresult} 
~ better rounded with pgfmathprintnumber \\

-1: \pgfmathparse{Test(-1)} 
\pgfmathresult ~ works \\
%\pgfmathprintnumber[precision=2]{\pgfmathresult} 
pgfmathprintnumber works not!
\end{document}

答案1

该命令\pgfmathprintnumber内部调用库\pgfmathfloatparsenumber的一部分fpu。浮点解析使用错误处理程序来处理无效数字,您可以重新定义该数字。

错误处理程序被调用/pgf/fpu/handlers/invalid number,有两个参数,原始输入和“不可读部分”。因为有两个参数,所以code 2 args应该使用键来公开#1#2。现在您可以打印原始输入作为错误处理的一部分:

\pgfkeys{/pgf/fpu/handlers/invalid number/.code 2 args={#1}}

然而,这还不够。根据 PGF 手册,错误处理程序旨在正确的无效输入,之后控制权将交还给\pgfmathfloatparsenumber(随后交给\pgfmathprintnumber)。这意味着您可以使用处理程序中的各种数学函数为 分配新值\pgfmathresult,或者什么也不做,然后\pgfmathresult将是 ,NaN就像最初调用 一样\pgfmathfloatparsenumber。然后 的值\pgfmathresult将传递给\pgfmathprintnumber并显示。

因此,上述定义将导致输出ERROR NaN,其中在错误处理程序中ERROR打印并通过进一步处理打印。#1NaN\pgfmathprintnumber

要得到仅有的原始输入和不是 NaN在输出中,可以使用更多修改。想法是修改pgfmath打印字符串的通用代码NaN,并将其转换为以切换为条件的字符串。错误处理程序可以将切换设置为 false,如果切换为 true,则打印代码可以打印字符串,如果切换为 false,则不打印任何内容,但将切换设置为 true,以确保NaN从其他地方调用时可以打印。

切换和代码修补功能由etoolbox

梅威瑟:

\documentclass[border=5mm, varwidth]{standalone}
\usepackage{tikz}
\usepackage{etoolbox}
\newtoggle{printnan}
\toggletrue{printnan}
\makeatletter
\patchcmd{\pgfmathfloatrounddisplaystyle@shared@impl}% patch the pgf command for printing NaN
{\hbox{NaN}}% find the following code
% replace by:
{\iftoggle{printnan}{\hbox{NaN}}% print normally if toggle is true
{\global\toggletrue{printnan}}}% print nothing and set toggle to true if it is false
{}{}
\makeatother
\makeatother
\pgfkeys{/pgf/fpu/handlers/invalid number/.code 2 args={#1\global\togglefalse{printnan}}}
\begin{document}
\def\x{5} % works

\pgfmathdeclarefunction{Test}{1}{%%
\pgfmathparse{#1==-1}%
\ifnum\pgfmathresult=1 \pgfmathparse{"ERROR"} \else% 
  \pgfmathparse{#1<0.01}% 
   \ifnum\pgfmathresult=1%
    \pgfmathparse{#1*1000}%
    \else \pgfmathparse{#1}%
    \fi%
\fi}%%

-1: \pgfmathparse{Test(-1)} 
\pgfmathresult ~ works \\
\pgfmathprintnumber[precision=2]{\pgfmathresult}
pgfmathprintnumber prints the input unchanged\\

123: \pgfmathparse{Test(123)}
 \pgfmathprintnumber[precision=2]{\pgfmathresult} 
~pgfmathprintnumber works \\

0.0001: \pgfmathparse{Test(0.0001)} 
\pgfmathresult ~works but strange result  \\
\pgfmathprintnumber[precision=2]{\pgfmathresult} 
~ better rounded with pgfmathprintnumber \\

\end{document}

结果:

在此处输入图片描述

相关内容