% Copyright 2007 by Mark Wibrow % % This file may be distributed and/or modified % % 1. under the LaTeX Project Public License and/or % 2. under the GNU Public License. % % See the file doc/generic/pgf/licenses/LICENSE for more details. % % This file provides basic macros for converting between bases. % % Version 0.0 08/03/2007 % \pgfmathbasetodec % % Convert a representation of an integer from % the spcified base to base 10. % % #1 - a macro to store the result. % #2 - the representation of a number (i.e. not a register) % #3 - the current base. % % e.g. % % \pgfmathbasetodec\mynumber{10111}{2} % % \mynumber <- 23 % \def\pgfmathbasetodec#1#2#3{% \pgfmath@checknumber{#2}% \pgfmath@checkbase{#3}% \def\pgfmath@base{#3}% \def\pgfmath@macro{#1}% \c@pgfmath@counta1\relax% \def\pgfmath@reversed{}% \expandafter\pgfmathbasetodec@#2\pgfmathbasetodec} \def\pgfmathbasetodec@#1{% \ifx\pgfmathbasetodec#1% \c@pgfmath@countb0% \divide\c@pgfmath@counta by\pgfmath@base\relax% \expandafter\pgfmathbasetodec@@% \else% \edef\pgfmath@reversed{\pgfmath@reversed#1}% \expandafter\multiply\expandafter\c@pgfmath@counta\pgfmath@base\relax% \expandafter\pgfmathbasetodec@% \fi} \def\pgfmathbasetodec@@{\expandafter\pgfmathbasetodec@@@\pgfmath@reversed\pgfmathbasetodec} \def\pgfmathbasetodec@@@#1{% \ifx\pgfmathbasetodec#1\relax% \expandafter\edef\pgfmath@macro{\the\c@pgfmath@countb}% \let\pgfmath@next\pgfmathbasetodec@@@@% \else% \chardef\pgfmath@charnum`#1\relax% \c@pgfmath@countc\pgfmath@charnum% \ifnum\c@pgfmath@countc>96\relax% \advance\c@pgfmath@countc-87\relax% \else \ifnum\c@pgfmath@countc>64\relax% \advance\c@pgfmath@countc-55\relax% \else \advance\c@pgfmath@countc-48\relax% \fi\fi% \ifnum\c@pgfmath@countc<\pgfmath@base\relax% \multiply\c@pgfmath@countc\c@pgfmath@counta\relax% \advance\c@pgfmath@countb\c@pgfmath@countc% \divide\c@pgfmath@counta by\pgfmath@base\relax% \let\pgfmath@next\pgfmathbasetodec@@@% \else \pgfmath@error{Digit `#1' invalid for base \pgfmath@base}% \let\pgfmath@next\relax% \fi% \fi% \pgfmath@next} \def\pgfmathbasetodec@@@@{% \expandafter\pgfmath@ensurenumberlength\expandafter{\pgfmath@macro}% } % \pgfmathdectobase % % Convert a representation of an integer from % base 10 to the spcified base. Letters for bases % greater than 10 are in lowercase. % % #1 - a macro to store the result. % #2 - a number in base 10 (in a macro, not a register) % #3 - the required base. % % e.g. % % \pgfmathdectobase\mynumber{127}{16} % % \mynumber <- 7f % \def\pgfmathdectobase#1#2#3{% \pgfmath@checknumber{#2}% \pgfmath@checkbase{#3}% \c@pgfmath@counta#2\relax% \def#1{}% \pgfmathloop \ifnum\c@pgfmath@counta>0\relax% \c@pgfmath@countb\c@pgfmath@counta% \divide\c@pgfmath@countb#3\relax% \multiply\c@pgfmath@countb-#3\relax% \advance\c@pgfmath@countb\c@pgfmath@counta% \edef#1{\csname pgfmath@lowercase digit@\the\c@pgfmath@countb\endcsname#1}% \divide\c@pgfmath@counta#3\relax% \repeatpgfmathloop% \pgfmath@ensurenumberlength{#1}} % \pgfmathdectoBase % % Convert a representation of an integer from % base 10 to the spcified base. Letters for bases % greater than 10 are in uppercase. % % #1 - a macro to store the result. % #2 - a number in base 10 (in a macro, not a register) % #3 - the required base. % % e.g. % % \pgfmathdectoBase\mynumber{127}{16} % % \mynumber <- 7F % \def\pgfmathdectoBase#1#2#3{% \pgfmath@checkbase{#3}% \pgfmath@checknumber{#2}% \c@pgfmath@counta#2\relax% \def#1{}% \pgfmathloop \ifnum\c@pgfmath@counta>0\relax% \c@pgfmath@countb\c@pgfmath@counta% \divide\c@pgfmath@countb#3\relax% \multiply\c@pgfmath@countb-#3\relax% \advance\c@pgfmath@countb\c@pgfmath@counta% \edef#1{\csname pgfmath@uppercase digit@\the\c@pgfmath@countb\endcsname#1}% \divide\c@pgfmath@counta#3\relax% \repeatpgfmathloop% \pgfmath@ensurenumberlength{#1}} \def\pgfmath@createdigits{% \def\pgfmath@digitstyle{lowercase digit}% \c@pgfmath@counta0\relax% \pgfmath@createdigits@0123456789abcdefghijklmnopqrstuvwxyz\pgfmath@createdigits% \def\pgfmath@digitstyle{uppercase digit}% \c@pgfmath@counta0\relax% \pgfmath@createdigits@0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\pgfmath@createdigits} \def\pgfmath@createdigits@#1{% \ifx\pgfmath@createdigits#1\relax% \else% \expandafter\pgfmath@def\expandafter{\pgfmath@digitstyle}{\the\c@pgfmath@counta}{#1}% \advance\c@pgfmath@counta1\relax% \expandafter\pgfmath@createdigits@% \fi} \pgfmath@createdigits % \pgfmathbasetobase % % Convert a representation of an integer from % between the specified bases. Letters for target % bases greater than 10 are in lppercase. % % #1 - a macro to store the result. % #2 - a number (in a macro, not a register) % #3 - the source base. % #4 - the target base. % % e.g. % % \pgfmathbasetobase\mynumber{4321}{5}{9} % % \mynumber <- 721 % \def\pgfmathbasetobase#1#2#3#4{% \pgfmathbasetodec{\pgfmath@temp}{#2}{#3}% \pgfmathdectobase{#1}{\pgfmath@temp}{#4} } % \pgfmathbasetobase % % Convert a representation of an integer from % between the specified bases. Letters for target % bases greater than 10 are in lppercase. % % #1 - a macro to store the result. % #2 - a number (in a macro, not a register) % #3 - the source base. % #4 - the target base. % % e.g. % % \pgfmathbasetobase\mynumber{1234}{5}{12} % % \mynumber <- 142 % \def\pgfmathbasetoBase#1#2#3#4{% \pgfmathbasetodec{\pgfmath@temp}{#2}{#3}% \pgfmathdectoBase{#1}{\pgfmath@temp}{#4} } \def\pgfmath@checkbase#1{% \ifnum#1<2\relax% \pgfmath@error{Cannot process numbers in base `#1'.}% \else% \ifnum#1>36\relax% \pgfmath@error{Cannot process numbers in base `#1'.}% \fi\fi} \def\pgfmath@checknumber#1{% \expandafter\pgfmath@checknumber@#1\pgfmath@} \def\pgfmath@checknumber@#1#2\pgfmath@{% \ifx#1-% \pgfmath@error{Cannot process negative numbers.}% \fi} % \pgfmath@ensurenumberlength % % Internal macro for making a representation of a number have % a specific length, byt prefixing zeros to the number. % % #1 - a macro contatining a representation of an integer. % #2 - the number of digits to ensure. % % e.g. % % \foo <- 7FF % % \pgfmathsetnumberlength{8}% % \pgfmath@ensurenumberlength\foo % % \foo <- 000007FF % \def\pgfmath@ensurenumberlength#1{% \def\pgfmath@tempa{#1}% \expandafter\c@pgfmath@counta\pgfmath@basenumberlength\relax% \expandafter\pgfmath@ensurenumberlength@#1\pgfmath@ensurenumberlength} \def\pgfmath@ensurenumberlength@#1{% \ifx\pgfmath@ensurenumberlength#1\relax% \expandafter\pgfmath@ensurenumberlength@@% \else% \advance\c@pgfmath@counta-1\relax% \expandafter\pgfmath@ensurenumberlength@ \fi} \def\pgfmath@ensurenumberlength@@{% \edef\pgfmath@tempb{\pgfmath@tempa}% \pgfmath@ensurenumberlength@@@} \def\pgfmath@ensurenumberlength@@@{% \ifnum\c@pgfmath@counta>0\relax% \advance\c@pgfmath@counta-1\relax% \edef\pgfmath@tempb{0\pgfmath@tempb}% \expandafter\pgfmath@ensurenumberlength@@@% \fi% \expandafter\edef\pgfmath@tempa{\pgfmath@tempb}} \def\pgfmathsetbasenumberlength#1{\def\pgfmath@basenumberlength{#1}} \pgfmathsetbasenumberlength{1}%