首藤です。

> > > FreeBSD/i386 の浮動小数点例外の関する話題が、
> > > http://www.jp.freebsd.org/ports-jp/ にありました。

> > > FreeBSD で他のシステムの振舞に合わせる場合、次のようなコードを
> > > main の入口と出口に入れるといいかもしれません。
> >
> > 「main() の出口で元に戻せ」ということは、
> > FPU の control word はプログラムが終了しても自動的にリセットはされない、
> > ということですよね。

さすがにこんなことはないですよね…

> FPU のレジスタの値も、他のレジスタ同様コンテキスト
> スイッチで退去/復元されるものと理解していました。

今 FreeBSD マシンにログインできないので、手もとの Linux 2.2.1 で
実験したところ、あるプロセスでの変更は他プロセスに影響を与えません。
当然ですね…
FreeBSD でも、FPU control word はプロセスのコンテクストに含まれると思います。

> そう考えると、main() の出口で戻しているのは、、なんか変!

変ですね。
何もプログラム終了時に FPU control word を元に戻す必要はないはずです。

FreeBSD の ports-jp ML に文章を書いた人の勘違いでしょうか。
  http://www.jp.freebsd.org/ports-jp/


> > と言っても、floatingpoint.h で提供されるインタフェースが
> > x86 以外を考慮していないようなので(2.2.7R で確認)、
>
> man fpgetround(3) によると
>  HISTORY
>       These routines are based on SysV/386 routines of the same name.

> Solaris for x86 とかには、 fpsetmask() はあるのでしょうか?

少なくとも Linux 2.2.1/x86 に fpsetmask(), fpgetround() はありません。

> あるなら、初期状態でマスクは、どのような値なのでしょうか?

Linux では (以前書いたように) 0x37f です。
ところが、/usr/include/fpu_control.h (glibc 2.0.7) に以下の記述があります。

 * The hardware default is 0x037f. I choose 0x1372.

Linux では ハードウェアの初期値のままになっている、
ということでしょうか。


> x87 を使った UNIX に普遍的な問題なのでしょうか?

FreeBSD 以外にも、わざと一部の例外処理をマスクしていない OS が
あるかもしれないですね。
#NetBSD, OpenBSD なんかはその線が濃厚か?

ruby としては SIGFPE で終了してしまうのは困るわけで、
マスクしてしまうか、SIGFPU が起きないようなコードにするか、
の必要がありそうです。

x86 の FPU といえば、FPU 内で浮動小数点数を 64bit で扱う 
(FreeBSD)か 80bit で扱う (Linux) かの問題もあります。こ
れによって計算結果が変わり得るので。でもこれを言い出すと、
異なる種類の FPU での計算結果は同じになるのか?という問
題にぶつかります。

最悪、プラットフォームが異なると ruby スクリプトの
実行結果が異なる、という現象が起こり得ます。
処理系依存を認めていた過去の言語では問題なかったけれど、
Java などでは…

SHUDO Kazuyuki/首藤一幸   私をたばねないで あらせいとうの花のように
  shudoh / muraoka.info.waseda.ac.jp