[Efont-devel] Re: 和田研フォントキットの Common Lisp 移植版を公開しました

Back to archive index

KANOU Hiroki kanou****@khdd*****
2004年 5月 23日 (日) 00:31:31 JST


狩野です。

岩井さん、trnasform.l のバグの指摘ありがとうございました。

岩井さんの新たに指摘された以下の問題点は、私も以前体験していますので、
Debian 固有の問題ではないように思います。

> Debian GNU/Linux(sid)のcmucl 18e-9で、wadalab-fontkitのビルドに失敗し
> ます。具体的にはbuild/skeleton/mincho/min-66.lを作る段階で、添付したロ
> グのようなエラーを吐いてビルドが止まります。

岩井さんのご指摘のように (defparameter source-load t) とすれば (これは、
コンパイルしないでインタプリタとして実行すれば) 正しく動作するのも
同じです。

結論から言えば、lisp コンパイラの (微妙な) バグのようです。
http://khdd.net/kanou/kangae/2004/May.html#16.1 に書きましたが、
私の試した cmucl 18e (FreeBSD 用) では、

(defvar y 2.0d0)
(print (sqrt (float y)))

という 2 行のコードを評価したとき、コンパイルせずに実行するか
コンパイルして実行するかで結果が変わります。

正しくは、常に
1.4142135623730951d0 
と倍精度の整数になるはずですが、コンパイルすると
1.4142135 
と単精度になってしまいます。
まずはこの現象が起こるかお確かめいただけないでしょうか。

この問題に対する最も簡単な解決策は、cmucl の最新のスナップショットを使用
することです。README にあるバージョンでしたら、正しく動くものと思います 
(他のバージョンで動作した実績があればご指摘いただければ幸いです)。

このエラーは、二つの並んだ部品の間の距離を求める処理の中で出てくる不等式の
評価が正しく行えずに発生しています。Utilisp では float は C の double 型で
実装されていましたので、単精度浮動小数点数では精度が絶対的に不足している
ようです。特に誤差にセンシティブな関数 equation_ts と、それを呼び出している
crosst1 でマクロ dfloat (compat.l) で倍精度に変換した数値を使用し、演算後に
結果を sfloat で単精度に戻しています。

本質的には、2 本の直線がほとんど平行に近いとき、片方の線がごく僅かに平行
移動しただけでも、交点の位置が大きく変わるのが原因です。不幸にして、交点の
X 軸が [0, 1] の内側にあるか外側にあるかという判定が誤差のせいで間違って
判定されてしまう時もあります。誤差に本質的に強いアルゴリズムに書き換える
方法がありましたらぜひ情報をいただければと思います。

狩野 宏樹  <kanou****@khdd*****>



Efont-devel メーリングリストの案内
Back to archive index