我需要一个功能
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
打印并通过进一步处理打印。#1
NaN
\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}
结果: