2014年3月8日土曜日

LaTeXの四則演算を考える

プログラム言語として見たLaTeXについて書いていきます。
長くなるので、今回は計算だけに内容を絞ります。

1、数値を計算する
TeXとC言語の計算の書き方を比べていきます。
緑がC言語流、青字がTeX流です。
%変数の定義
int a, b, c;

\newcount\vA
\newcount\vB
\newcount\vC
\newcount\vD

vC = f(vA, vB)
を考える。


%足し算
vC = vA + vB;

\vC = \vA
\advance\vC by \vB


%引き算
vC = vA - vB;

\vC = \vA
\advance\vC by -\vB


%かけ算
vC = vA * vB;

\vC = \vA
\multiply\vC by \vB


%整数の割り算
vC = vA / vB;

\vC = \vA
\divide\vC by \vB


%剰余算(割ったあまりを求める)
vC = vA % vB;

\vC = \vA
\vD = \vA
\divide\vD by \vB
\multiply\vD by \vB
\advance\vC by -\vD


%小数の割り算(TeXでは固定小数点小数を使うしかない)

float fa, fb, fc;
fa = 10.f, fb = 3.f;
fc = fa / fb;

fcには3.333333が入る(有効桁数が6のとき)。

\vA = 10
\vB = 3
\vC = \vA
\multiply\vC by 1000
\divide\vC by \vB
vCには3333が入っているので、これを3333/1000とみなす。
上で見た通り、(後発のスタイルファイルがあるかもしれませんが、それを除くとすれば)TeXにはいくつかのものがありません。
  1. 非負整数や浮動小数点小数が無い。
  2. 剰余算が無い。
  3. returnを持たないため、関数は値を返さない。
2、スコープの違い
また、TeXにはローカル変数やスコープがないため、下のような違いがあります。

int out_of_scope;
{
____int value;
____value = 10;
____out_of_scope = 10;
}

printf("%d", out_of_scope); //書ける
printf("%d", value); //コンパイルが通らない
//out_of_scopeにはアクセスできるが、valueにはアクセスできない。
//{}を過ぎると変数は破棄される。



\newcount\outofscope
{
____\newcount\value
____\value = 10
____\outofscope = 10
}

\the\outofscope %10が出る。
\the\value %同じく10が出る。
%どちらでもアクセスできる。
%{}を書いてもスコープの意味はないため、定義した変数はプログラムの終了まで保持される。
TeX流も便利そうだと思うかもしれませんが、これでは困ることが出てきます。

int itl, limit;
itl = 0;
limit = 300;
while (itl < limit) {

____int value;
____value = 0;
____itl++;
}

//C言語であれば、こんなコードでプログラムが続行不能になることはありません。
//変数valueが定義されますが、ループを一回繰り返すたびにvalueが破棄されているためです。



\newcount\itl
\newcount\limit
\itl = 0
\limit = 300

\loop
____\newcount\value
____\value = 0
____\advance\itl by 1
\ifnum\itl<\limit \repeat

%同じ意味のコードですが、TeXでは実行できません。
%ループを一回繰り返すたびにvalueが確保されています。
%同じ名前でも新しく確保されるため、結果として300個のvalue変数を確保しようとします。
%LaTeXでは256個を超える変数カウンタは確保できませんので、ループ中にハングします。
関数の中で\newcountを使ってしまうと、ループが原因でハングすることがあります。
そのため、グローバル変数にローカル変数らしい振る舞いをさせることで対応します。
ざっくりと以上です。それでは、また。

0 件のコメント:

コメントを投稿