1

TeXで進数変換したいという話2

45
0
$$$$

前回 の続き

前回は10進数を16進数に変換したり,2進数を10進数に変換するマクロを作りました.そうすると,2進数を16進数に変換したくなりますね.
これは$\verb|\DTH|$$\verb|\BTD|$を組み合わせれば良さそうに思いますが,実はここに大きな落とし穴があって,前回の実装方法ではうまくいきません(というより,前回は組み合わせることを想定した実装にしていませんでした).

うまくいかない理由を説明します.とは言っても,Mathlog で$\mathrm\TeX$言語のあれやこれやを話すのは少し憚られるので簡潔に言うと,$\verb|\BTD|$を(先頭)完全展開させようとしたとしても,再帰によって条件分岐に用いたトークンである$\verb|\else|$$\verb|\fi|$が残ることで,数値を受け取るはずの$\verb|\DTH|$にそれらが渡されてエラーが起きるのです.

そこで,条件分岐の処理を分離することでこの問題を解決します.

\def\xx@ifx#1{%
$\quad$\ifx\xx@relax#1\xx@relax
$\qquad$\expandafter\@firstoftwo%
$\quad$\else
$\qquad$\expandafter\@secondoftwo%
$\quad$\fi%
}
\def\xx@ifnum#1{%
$\quad$\ifnum#1<16
$\qquad$\expandafter\@firstoftwo%
$\quad$\else
$\qquad$\expandafter\@secondoftwo%
$\quad$\fi%
}

を定義し,$\verb|\xx@DTH|$$\verb|\xx@BTD|$の定義を次のように書き直します.

\def\xx@DTH#1#2{%
$\quad$\xx@ifnum{#1}
$\qquad${\xx@DTA{#1}#2}
$\qquad${\xx@DTH{\the\numexpr(#1*2-16)/(16*2)\relax}{\xx@DTA{\the\numexpr#1-(#1*2-16)/(16*2)*16\relax}#2}}%
}

\def\xx@BTD#1#2#3\xx@relax{%
$\quad$\xx@ifx{#3}
$\qquad${\the\numexpr#1*2+#2\relax}
$\qquad${\xx@BTD{\the\numexpr#1*2+#2\relax}#3\xx@relax}%
}

この修正により,たとえば
$$ \verb|\expandafter\DTH\expandafter{\romannumeral-`?\BTD{1100100}}| $$
などとすると,2進数の1100100が16進数の64に変換されて出力されます.
これでもう安心して進数変換ができますね!

それではみなさま,よき$\mathrm\TeX$ライフを.

投稿日:4日前
数学の力で現場を変える アルゴリズムエンジニア募集 - Mathlog served by OptHub

この記事を高評価した人

高評価したユーザはいません

この記事に送られたバッジ

バッジはありません。

投稿者

約数関数、数列関係の記事を中心に書いていきます。 記事の内容に間違いがあれば教えてくれるとありがたいです。

コメント

他の人のコメント

コメントはありません。
読み込み中...
読み込み中