2009年12月26日土曜日

[Perl] %d でフォーマットする時の注意点 (printf/sprintf)

Perl で文字列をフォーマットする時に使う printf/sprintf。
大きな数値に対して %d でフォーマットすると、思わぬ結果になることがあるのでご注意を。
printf("2147483646:  %d\n", 2147483646);  # 2147483646
printf("2147483647:  %d\n", 2147483647);  # 2147483647
printf("2147483648:  %d\n", 2147483648);  # -2147483648
printf("2147483649:  %d\n", 2147483649);  # -2147483647
上記の様に、2147483648 を越えてから符号がマイナスになっています。
これは、%d が SIGNED INTEGER (-2147483648~2147483647) を意味しているからです。
2147483648 を更に大きくしていくと徐々に -1 に近づいていき、
これ以上大きくなると以下の様に -1 以外返さなくなります。
printf("10000000000: %d\n", 10000000000); # -1
乗算等で知らず知らずのうちに大きな値になったものについては要注意です。
解決策は、%d ではなく %s を使うこと。
大きな数値でもそのまま文字列としてフォーマットされます。
printf("10000000000: %s\n", 10000000000); # 10000000000
地味にハマるところなのでご注意を。

0 件のコメント: