鳳鳴は祖父の俳号

日記 メモ そんなの

awk/gawkで加算の結果がなんかおかしい 調査中 →doubleによる制限事項でした

動作環境: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

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

MacOSX Tiger(PPC)でのgawk4.0.0でも再現。CPUアーキ依存ではない?

あ!これっぽい「木村さんが言うには、gawk は dobule で数値を扱っていて、double の mantissa は 52bit (+けちビット) あるので、通常の gawk でも 113383 は計算できます。」
http://gauc.no-ip.org/wiki.cgi?page=BBS-BBS%2F47

ツイッターで教えてもらいました:Thanks @ksmakoto
Twitter. It's what's happening.

結論:awkの内部演算(double)による制限事項