2016年3月12日土曜日

\(\TeX\)カウンタ剰余演算子の実装

\(\TeX\)のカウンタは四則演算はできるらしいが剰余演算子は無いっぽいので実装してみた。
ついでによくプログラミングで聞かれる数学的関数を幾つか実装してみた。→次の記事

まず\(\TeX\)のカウンタの演算子は加、乗除(と代入文)ができる。
詳しくはこちら http://www.geocities.co.jp/HeartLand-Poplar/1240/latex/value.html

加減乗除を組み合わせ剰余演算子のマクロを作る。


  1. \def\surplus#1#2{%
  2.         \newcount\n \newcount\m \newcount\t
  3.         \n=#1 \m=#2 \t=\n%
  4.         \divide \n by \m%
  5.         \multiply \n by \m%
  6.         \advance \t by -\n%
  7.         #1=\t\relax%
  8. }
\surplusは二項演算子で#1%#2を計算する
計算式は、n=#1,m=#2として
 n-(n/m)*m
除算\divideは切り捨てて整数値を返す(そもそもカウンタは整数値しか扱わない)のでこれであまりが計算できる。
カウンタ用演算子は多項演算とかいう高度なことはできないしカウンタの値を変更してしまい元の値は保持できないのでtにmの値をバックアップして順次計算していく。
ちなみに演算子には引き算がないがカウンタや数値の前に"-"をつけるだけで簡単に符号反転できるので加算\advanceで計算できる。

カウンタの演算子は
 \operator operand1 by operand2
の形(operandはカウンタ又は数値)か
 \operatoroperand1operand2
で実行できる。わざわざbyやスペースを入れた方が数値を扱うときは見やすかもしれない。

さて、剰余演算子ができたので実行してみるが、参考ページに\(\LaTeX\)はカウンタのインクリメントがあるのに\(\TeX\)には無いということだったのでインクリメント、デクリメントを実装した。(\(\LaTeX\)のカウンタは\(\TeX\)のと形式が違うため直接適用できない)
また形式が他と違って加算と符号反転の組み合わせになるのがなんか嫌だったので減算演算子もついでに書いておいた。


  1. \documentclass{article}

  2. \def\surplus#1#2{%略記
  3.         \newcount\n \newcount\m \newcount\t
  4.         \n=#1 \m=#2 \t=\n%
  5.         \divide\n\m%
  6.         \multiply\n\m%
  7.         \minus\t\n%
  8.         #1=\t\relax% %戻り値
  9. }

  10. \def\surplus#1#2{%
  11.         \newcount\n \newcount\m \newcount\t
  12.         \n=#1 \m=#2 \t=\n%
  13.         \divide \n by \m%
  14.         \multiply \n by \m%
  15.         \advance \t by -\n%
  16.         #1=\t\relax%
  17. }

  18. \def\minus#1#2{
  19.         \advance #1 by -#2
  20. }
  21. \def\increment#1{
  22.         \advance #1 by 1
  23. }
  24. \def\decrement#1{
  25.         \advance #1 by -1
  26. }

  27. \begin{document}
  28. \newcount\p \p=101 \newcount\q \q=13
  29. \surplus\p\q
  30. \the\p

  31. \increment\p
  32. \the\p

  33. \minus\p\q
  34. \the\p

  35. \end{document}

33,36,40行目でそれぞれ 101/13, (101/13=)10++, (10++=)11-13を計算している。
実行結果は

上手いこと行った。
ちなみに3~10行と12~19行で略記版とフルテクスト版で\surplusを宣言しているが\(\LaTeX\)の\newcommandでは名前が被るとエラーになるのと違い、\defは上書きされるのでこのドキュメントでは後者が生きている。


キヨシ関数で乱数を\ifoddにかけて場合分けをする操作があったが剰余演算子ができたのでもっと場合分けが増やせるようになった。
この関数は引数のカウンタの数値を上書きしてしまうため単に場合分けに使うだけなら次の記事のifprime関数のように別のカウンタに格納したものを呼び出すようにした方がいいかもしれない。

次の記事で一応ここで作ったインクリメントが活躍している。(ただ普通に+1するのとあんまり変わんないけど)

0 件のコメント:

コメントを投稿