メールの詳細(トピック表示)
はじめまして、houmei/竹下と申します。よろしくお願いします。
fibbuzzという、フィボナッチ数列に対してfizzbuzzをするという遊びをawkでやっていたところ、どうも答えが異なってしまう現象がおき悩んでいました。ある程度絞り込めましたのでご報告します。
動作環境:MacOSX(10.6.8) /標準のawkとhomebrewでインストールしたgawk
awk version 20070501
GNU Awk 4.0.0
実行例:
gawk 'BEGIN{print 5527939700884757+8944394323791464}'
→14472334024676220 ※最後の桁が"1"でない
なお、rubyでは正しく計算できています。
ruby 1.8.7 (2010-01-10 patchlevel 249) [universal-darwin10.0]
ruby -e 'print 5527939700884757+8944394323791464'
→14472334024676221
どういった境界で発生するのかまでは追求できていません。取り敢えずご報告まで。
読み込み中...-
MLNo.257
houmeiさん
(0) 2011/10/16 06:06 [メール表示する]

竹下です。gawk3.1.6でも再現しました。(ideone.com) http://ideone.com/37P7Y
さらに絞り込んでみました。
16進表示に直しました:(clisp)
Break 1 [4]> (format nil "~X" 5527939700884757)
"13A3A1C2360515"
Break 1 [4]> (format nil "~X" 8944394323791464)
"1FC6E116668E68"
再現確認:
$ gawk 'BEGIN{print 0x13A3A1C2360515+0x1FC6E116668E68}'
14472334024676220
絞り込み:
$ gawk 'BEGIN{print 0x13000000000005+0x1F000000000008}'
14073748835532812
$ gawk 'BEGIN{print 0x01000000000000+0x1F000000000001}'
9007199254740992
$ gawk 'BEGIN{print 0x01000000000000+0x1E000000000001}'
8725724278030337
16進で13桁目の繰り上がりで末尾の'1'が加算されていないように見えます。
同じ繰り上がりでも0x01.. + 0x0F.. ではうまくいきます。
$ gawk 'BEGIN{print 0x01000000000000+0x0F000000000001}'
4503599627370497

-
MLNo.258
ほげむたさん
(0) 2011/10/16 11:45 [メール表示する]

木村です。
2011/10/16 houmei:
> はじめまして、houmei/竹下と申します。よろしくお願いします。
>
> fibbuzzという、フィボナッチ数列に対してfizzbuzzをするという遊びをawkでやっていたところ、どうも答えが異なってしまう現象がおき悩んでいました。ある程度絞り込めましたのでご報告します。
>
> 動作環境:MacOSX(10.6.8) /標準のawkとhomebrewでインストールしたgawk
> awk version 20070501
> GNU Awk 4.0.0
> 実行例:
> gawk ''BEGIN{print 5527939700884757+8944394323791464}''
> →14472334024676220 ※最後の桁が"1"でない
>
> なお、rubyでは正しく計算できています。
> ruby 1.8.7 (2010-01-10 patchlevel 249) [universal-darwin10.0]
>
> ruby -e ''print 5527939700884757+8944394323791464''
> →14472334024676221
>
> どういった境界で発生するのかまでは追求できていません。取り敢えずご報告まで。
homebrew とあるのでgccが使えると思いますが、こんなのをコンパイル&実行してみてください。
#include
double getx() {return 5527939700884757.0;}
double gety() {return 8944394323791464.0;}
int
main()
{
int x, y;
printf("%f\n", getx()+gety());
printf("%f\n", 14472334024676220.0);
printf("%f\n", 14472334024676221.0);
printf("%f\n", 14472334024676222.0);
printf("%f\n", 14472334024676223.0);
return 0;
}
こんな出力になると思います
14472334024676220.000000
14472334024676220.000000
14472334024676220.000000
14472334024676222.000000
14472334024676224.000000
2**53-1 = 9007199254740991 なので、double で表現できないところに行っちゃってますね。
では。
--
木村浩一/KIMURA Koichi
I thought what I''d do was, I''d pretend I was one of those deaf-mutes
or shoud I?
mail kbk at kt.rim.or.jp
web www.kt.rim.or.jp/~kbk/zakkicho/index.html

- MLNo.259 houmeiさん (0) 2011/10/16 13:15 [メール表示する]

