論理計算を表示する

論理計算を表示する

生徒のために、基数 b (b は 2 から 36 までの整数) の 2 つの数値間の論理計算 (AND、OR、XOR) をビットごとに表示するマクロを作成したいと考えています。

パラメータは number1、number2、b です。number1、number2 は基数 b で記述されます。マクロは number1 と number2 を 2 進数に変換し、次の図に示すように計算を実行します。

写真7 写真8 写真9

誰かこれを作った人いますか?

ザビエル。

答え1

プログラミングするのはとても楽しいです。:-)

\documentclass{article}
\usepackage{xparse,booktabs}

\ExplSyntaxOn
\NewDocumentCommand{\showbitwiseand}{mm}
 {
  \bitwise_show:Nnnn \bitwise_and:nnn { #1 } { #2 } { AND }
 }
\NewDocumentCommand{\showbitwiseor}{mm}
 {
  \bitwise_show:Nnnn \bitwise_or:nnn { #1 } { #2 } { OR }
 }
\NewDocumentCommand{\showbitwisexor}{mm}
 {
  \bitwise_show:Nnnn \bitwise_xor:nnn { #1 } { #2 } { XOR }
 }

\NewDocumentCommand{\bitwiseand}{mm}
 {
  \bitwise_compute:Nnnn \bitwise_and:nnn { #1 } { #2 } { AND }
 }
\NewDocumentCommand{\bitwiseor}{mm}
 {
  \bitwise_compute:Nnnn \bitwise_or:nnn { #1 } { #2 } { OR }
 }
\NewDocumentCommand{\bitwisexor}{mm}
 {
  \bitwise_compute:Nnnn \bitwise_xor:nnn { #1 } { #2 } { XOR }
 }

\cs_new_protected:Nn \bitwise_show:Nnnn
 {
  \ensuremath
   {
    #1 { #2 } { #3 } { 0 }
    \begin{array}{r@{}l}
    \lbrack\int_to_bin:n { #2 }\rbrack & \sb{2} \\
    \mathrm{#4}\quad
    \lbrack\int_to_bin:n { #3 }\rbrack & \sb{2} \\
    \midrule
    \lbrack\l__bitwise_out_tl\rbrack & \sb{2} \\
    \multicolumn{2}{l}{#2 \mathbin{\mathrm{#4}} #3 = \l__bitwise_decimal_tl}
    \end{array}
   }
 }

\cs_new_protected:Nn \bitwise_compute:Nnnn
 {
  #2 \mathbin{\mathrm{#4}} #3 = #1 { #2 } { #3 } { 1 }
 }

\tl_new:N \l__bitwise_first_tl
\tl_new:N \l__bitwise_second_tl
\tl_new:N \l__bitwise_out_tl
\tl_new:N \l__bitwise_decimal_tl
\int_new:N \l__bitwise_log_int

\cs_new_protected:Nn \bitwise_and:nnn
 {
  \__bitwise_set:nn { #1 } { #2 }
  \__bitwise_generic:N \__bitwise_and:n
  \__bitwise_normalize:
  \int_compare:nF { #3 = 0 } { \l__bitwise_decimal_tl }
 }
\cs_new_protected:Nn \bitwise_or:nnn
 {
  \__bitwise_set:nn { #1 } { #2 }
  \__bitwise_generic:N \__bitwise_or:n
  \__bitwise_normalize:
  \int_compare:nF { #3 = 0 } { \l__bitwise_decimal_tl }
 }
\cs_new_protected:Nn \bitwise_xor:nnn
 {
  \__bitwise_set:nn { #1 } { #2 }
  \__bitwise_generic:N \__bitwise_xor:n
  \__bitwise_normalize:
  \int_compare:nF { #3 = 0 } { \l__bitwise_decimal_tl }
 }

\cs_new_protected:Nn \__bitwise_generic:N
 {
  \int_step_function:nnnN { 1 } { 1 } { \l__bitwise_log_int } #1
 }

\cs_new_protected:Npn \__bitwise_normalize:
 {
  \tl_reverse:N \l__bitwise_out_tl
  \tl_set:Nx \l__bitwise_decimal_tl { \int_from_bin:V \l__bitwise_out_tl }
  \tl_set:Nx \l__bitwise_out_tl { \int_to_bin:V \l__bitwise_decimal_tl }
 }
\cs_generate_variant:Nn \int_to_bin:n { V }
\cs_generate_variant:Nn \int_from_bin:n { V }

\cs_new_protected:Nn \__bitwise_and:n
 {
  \tl_put_right:Nx \l__bitwise_out_tl
   {
    \int_eval:n
     {
      \tl_item:Nn \l__bitwise_first_tl { #1 }
      *
      \tl_item:Nn \l__bitwise_second_tl { #1 }
     }
   }
 }

\cs_new_protected:Nn \__bitwise_or:n
 {
  \tl_put_right:Nx \l__bitwise_out_tl
   {
    \int_eval:n
     {
      \int_min:nn { 1 }
       {
        \tl_item:Nn \l__bitwise_first_tl { #1 }
        +
        \tl_item:Nn \l__bitwise_second_tl { #1 }
       }
     }
   }
 }

\cs_new_protected:Nn \__bitwise_xor:n
 {
  \tl_put_right:Nx \l__bitwise_out_tl
   {
    \int_eval:n
     {
      \int_if_odd:nTF
       {
        \tl_item:Nn \l__bitwise_first_tl { #1 }
        +
        \tl_item:Nn \l__bitwise_second_tl { #1 }
       }
       { 1 } { 0 }
     }
   }
 }

\cs_new_protected:Nn \__bitwise_set:nn
 {
  \tl_clear:N \l__bitwise_out_tl
  % make the binary representations
  \tl_set:Nx \l__bitwise_first_tl { \int_to_bin:n { #1 } }
  \tl_set:Nx \l__bitwise_second_tl { \int_to_bin:n { #2 } }
  % reverse the token lists
  \tl_reverse:N \l__bitwise_first_tl
  \tl_reverse:N \l__bitwise_second_tl
  % make them equal length
  \int_compare:nNnTF { \tl_count:N \l__bitwise_first_tl } > { \tl_count:N \l__bitwise_second_tl }
   {
    \tl_put_right:Nx \l__bitwise_second_tl
     {
      \prg_replicate:nn { \tl_count:N \l__bitwise_first_tl - \tl_count:N \l__bitwise_second_tl } { 0 }
     }
   }
   {
    \tl_put_right:Nx \l__bitwise_first_tl
     {
      \prg_replicate:nn { \tl_count:N \l__bitwise_second_tl - \tl_count:N \l__bitwise_first_tl } { 0 }
     }
   }
  \int_set:Nn \l__bitwise_log_int { \tl_count:N \l__bitwise_first_tl }
 }
\ExplSyntaxOff

\begin{document}

\[
\showbitwiseand{93}{208}
\qquad
\showbitwiseor{93}{208}
\qquad
\showbitwisexor{93}{208}
\]

In line:
\begin{itemize}
\item $\bitwiseand{93}{208}$
\item $\bitwiseor{93}{208}$
\item $\bitwisexor{93}{208}$
\end{itemize}

\end{document}

ここに画像の説明を入力してください

関連情報