Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Is there a way to access each digit of a macro returned by \pgfmathdectobase (or \pgfmathresult) which is a binary number ? This would be useful for a function which prints the power set of a given set (according to binary representations of numbers between 0 and 2^|given set|).

I can think of two versions 1) convert macro to an array and loop or 2) calculate size of macro and loop with \foreach if there is way to access the digits. Unfortunately I was not able to find anything near in the pgfmanual.

Also another possible solution would be with bit-masks. Does tikz support anything like that? Or any idea on a package that does?

I would be happy with any other package that can use the results from \pgfmathdectobase, too, if there is way to use it outside of tikz. Thanks!

share|improve this question
    
I have been using the {xstring} package for traversing strings, so think that you should be able to traverse it with \StrLeft along with \StrGobbleLeft. –  Peter Grill Jun 26 '11 at 19:09
    
can you perhaps clarify what you are trying to do with the digits when "accessing" them? –  Bruno Le Floch Jun 27 '11 at 1:12
    
@Bruno yes sure. I'm trying to build a function which prints the power set of a given set and figured, mapping binary digits from 0 to 2^|given set| to individual sets would be fine. –  panny Jun 27 '11 at 10:43
add comment

2 Answers

up vote 1 down vote accepted

In order to examine bit by bit the number, the scheme might be like this

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

In case you need to start from the less significant bit, you have to reverse the number first.

\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

There are many loops around for reversing strings. Maybe also PGF has some.

Instead of \temp you can use \pgfmathresult or the first argument to \pgfmathdectobase.

Of course you'll give more meaningful actions to \docasezero and \docaseone; these actions can use the value of \bitnumber. You can define a set of macros as

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

Here is a complete example (where I've changed a bit the programming style, using @ and constants provided by the LaTeX kernel):

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

enter image description here

share|improve this answer
    
This works perfectly fine for \processbinaryrev which is actually all I need. \processbinary causes some latex error. Unfortunately I barely understand the function ;) so I can't figure out where to put a counter such that I can remember the index of the digit recognized. –  panny Jun 27 '11 at 10:45
1  
Indeed there was a typo in \processbinary, I'll correct it and show also how to add a counter for the "place". –  egreg Jun 27 '11 at 11:21
    
@egreg Thanks for your edits! Is it possible the roman functions are never called? I've been trying to get them working but always the first two are called. Seems like bitnumber is not advanced, but I have no clue why not. –  panny Jun 28 '11 at 6:27
1  
@panny: the place where I wrote \bitnumber=-1 was wrong! –  egreg Jun 28 '11 at 9:17
    
@egreg Is it possible to integrate \bitnumber into an outputting function like \def\casezero{What to do when bit \bitnumber is 0\par} this would be useful when the bitstring length is not known at the beginning. –  panny Jun 28 '11 at 13:26
show 3 more comments

From your sub-question about bit masks I assume that you are dealing with bin/oct/dec/hex bases only? If that is the case, I strongly recommend using the bitset package by Heiko Oberdiek, which provides all common operators for bit-wise manipulation of data.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.