有没有办法访问由\pgfmathdectobase
(或\pgfmathresult
) 返回的宏的每个数字(二进制数)?这对于打印给定集合的幂集的函数很有用(根据 和 之间的数字的二进制表示0
)2^|given set|
。
我能想到两个版本 1) 将宏转换为数组并循环或 2) 计算宏的大小并循环(\foreach
如果有方法可以访问数字)。不幸的是,我在 pgfmanual 中找不到任何相关内容。
另一个可能的解决方案是使用位掩码。tikz 支持类似的东西吗?或者有没有什么包支持?
\pgfmathdectobase
如果有办法在 tikz 之外使用它,我也会很高兴使用可以使用结果的任何其他包。谢谢!
答案1
为了逐位检查数字,方案可能是这样的
\def\temp{10111}
\newcount\bitnumber
\def\slowbinary#1{%
\ifx\relax#1% end
\else
\advance\bitnumber by 1
\ifcase#1\relax\docasezero\or\docaseone\fi
\expandafter\slowbinary
\fi}
\def\processbinary#1{\bitnumber=-1 % reset the counter (we will start at 0)
\expandafter\slowbinary#1\relax}
\def\docasezero{\message{^^JZero seen}}
\def\docaseone{\message{^^JOne seen}}
\processbinary\temp
\processbinary{1010}
如果需要从较低有效位开始,则必须先反转数字。
\makeatletter
\def\processbinaryrev#1{%
\bitnumber=-1 % reset the counter (we will start at 0)
\@reverse{#1}%
\expandafter\slowbinary\@esrever \relax}
\def\@reverse#1{%
\edef\@temp{#1}%
\def\@esrever{}%
\loop\unless\ifx\@temp\@empty
\edef\@esrever{\expandafter\@car\@temp\@nil\@esrever}%
\edef\@temp{\expandafter\@cdr\@temp\@nil}%
\repeat}
\makeatother
\processbinaryrev\temp
有很多用于反转字符串的循环。PGF 可能也有一些。
\temp
您可以使用\pgfmathresult
或 的第一个参数来代替\pgfmathdectobase
。
当然,你会给\docasezero
和赋予更有意义的操作\docaseone
;这些操作可以使用 的值\bitnumber
。你可以定义一组宏作为
\def\docasezero{\csname casezero\romannumeral\bitnumber\endcsname}
\def\docaseone{\csname caseone\romannumeral\bitnumber\endcsname}
\def\casezero{What to do when bit 0 is 0}
\def\caseone{What to do when bit 0 is 1}
\def\casezeroi{What to do when bit 1 is 0}
\def\caseonei{What to do when bit 1 is 1}
\def\casezeroii{What to do when bit 2 is 0}
\def\caseoneii{What to do when bit 2 is 1}
...
这是一个完整的例子(我稍微改变了一下编程风格,使用了@
LaTeX 内核提供的常量):
\documentclass[a4paper]{article}
\makeatletter
\newcount\@bitnumber
\def\@slowbinary#1{%
\ifx\relax#1% end
\else
\advance\@bitnumber\@ne
\ifcase#1\relax\do@casezero\or\do@caseone\fi
\expandafter\@slowbinary
\fi}
\def\@reverse#1{%
\edef\@temp{#1}%
\def\@esrever{}%
\loop\unless\ifx\@temp\@empty
\edef\@esrever{\expandafter\@car\@temp\@nil\@esrever}%
\edef\@temp{\expandafter\@cdr\@temp\@nil}%
\repeat}
% \def\processbinary#1{\@bitnumber\m@ne
% \expandafter\@slowbinary#1\relax}
\def\processbinaryrev#1{\@reverse{#1}\@bitnumber=-1
\expandafter\@slowbinary\@esrever \relax}
\def\do@casezero{\csname casezero\romannumeral\@bitnumber\endcsname\relax}
\def\do@caseone{\csname caseone\romannumeral\@bitnumber\endcsname\relax}
\makeatother
\def\casezero{What to do when bit 0 is 0\par}
\def\caseone{What to do when bit 0 is 1\par}
\def\casezeroi{What to do when bit 1 is 0\par}
\def\caseonei{What to do when bit 1 is 1\par}
\def\casezeroii{What to do when bit 2 is 0\par}
\def\caseoneii{What to do when bit 2 is 1\par}
\def\casezeroiii{What to do when bit 3 is 0\par}
\def\caseoneiii{What to do when bit 3 is 1\par}
\def\casezeroiv{What to do when bit 4 is 0\par}
\def\caseoneiv{What to do when bit 4 is 1\par}
\def\casezerov{What to do when bit 5 is 0\par}
\def\caseonev{What to do when bit 5 is 1\par}
\def\temp{10111}
\begin{document}
\temp
\processbinaryrev\temp
\bigskip
101110
\processbinaryrev{101110}
\end{document}
答案2
从您关于位掩码的子问题中,我假设您只处理二进制/八进制/十进制/十六进制?如果是这样,我强烈建议使用位集Heiko Oberdiek 编写的包,提供了对数据进行按位操作的所有常见运算符。