木村です. > 鶴谷さん [FreeBSD-users-jp 91686] Re: long double の bug ? について > おそらくは、 > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17778 > が原因でgccにこんなコードが挿入されたのだと思うのですが、 この Bugzilla での話とその後の流れを要約すると,次のようになります.
(1) FreeBSD/i386 においては,FPU の精度は仮数部で 53bit に設定され, 浮動小数点数の定数は long double であっても 53bit に丸められる. (2) gcc 3.3.5 までは定数はその通りに丸められていたのだが,3.4.2 ではそれがきちんとできていない. (3) 以上の主張に基づいて,丸めが正しく行なわれるように修正した. それが ChangeLog (例えば /usr/src/contrib/gcc/config/ChangeLog) のこの部分である. Changes by: [メールアドレス保護] 2004-11-12 21:26:55 Log message: PR 17778 * config/i386/i386.h (TARGET_96_ROUND_53_LONG_DOUBLE): New. * config/i386/freebsd.h (SUBTARGET_OVERRIDE_OPTIONS): Remove. (TARGET_96_ROUND_53_LONG_DOUBLE): New. * config/i386/i386-modes.def (XF): Use it. (4) ただし,この修正が有効なのは 96bit long double の定数のみ. 128bit のそれに関しては手付かずであり,一貫性がなくなっている. --------------------------------------------------------------- このうち (1) の前半は正しいです.(それゆえ fpsetprec(FP_PE); で仮数部の精度を 64bit に切り換えているのです.) しかし,(1) の後半と (2) とは間違っていると考えます.私は今まで long double の定数が 53bit に丸められてしまった経験はありません.[1] 改めて検討した以下の環境でも lc = 3.14159265358979323846L; の丸めは 生じませんでしたし,逆に Bugzilla の方のテストコードの,gcc 3.3.5 で 丸めが正常に行なわれているとする結果は再現されませんでした.[2] (FreeBSD 4 系以前の printf() は long double に未対応なので使わず.) FreeBSD 4.9 + gcc 2.95.4, 3.0.4 FreeBSD 3.4 + gcc 2.7.2.3 FreeBSD 2.2.6 + gcc 2.2.2.1 加えて,この定数の丸めについて記した文書も見つかりません. すなわち,(3) の修正に至った前提である「FreeBSD/i386 においては, 浮動小数点数の定数は long double であっても 53bit に丸められる.」 の真偽を再確認する必要があると考えます.その後, ・偽ならば (3) の修正は元に戻してもらう. ・真ならば,その「仕様」を見直して Linux, Mac OS X, FreeBSD/amd64 に合わせてもらう.(難しいでしょうね.) ・真偽いずれであっても,(4) の一貫性の問題は修正してもらう. と話が素直に進んで欲しいところです. 週末あたりにこの質問から入るような send-pr をしようと思っています. Bugzilla でなく FreeBSD の土俵の方が良いような気がするからです. [1] そもそも,(1) の後半が真であるとすれば,FreeBSD + i386 の 環境では double でなく long double を使う理由に乏しいのです. [2] 皆様の環境での追試は結構です.確認したいのは動作よりも仕様 だからです.仕様の情報をお持ちの方はお知らせ下さい. Satoshi Kimura ([メールアドレス保護])