むかしむかし、王子の命を救った賢い召使いがいました。 王様は、召使いが望むものなら何でも報酬として与えると約束しました。 王様がチェスを愛していることを知っていた召使いは、小麦の粒がほしいと王様に伝えました。 チェス盤の最初のマスに1粒、次のマスからはマスが進むごとに粒の数が2倍になるように、と。
チェス盤の上にある小麦の粒の数を計算しましょう。
チェス盤には64のマスがあります。 1マス目には1粒、2マス目には2粒、3マス目には4粒、というように、マスが進むごとに2倍になっていきます。
次のものを計算するコードを書きましょう。
デフォルトでは、awkの数値は倍精度浮動小数点数として表されます。これで得られる精度は53ビットです(マニュアルの表16.3を参照してください)。残念ながら、この演習を完了するには足りません(ネタバレ注意、あるテストでは63ビットの精度が必要です)。
「精度が足りない」というのは、次のような状態です。
$ gawk 'BEGIN {
n = 2 ^ 54
if (n == n + 1)
print "not enough precision"
else
print "OK"
}'
not enough precision
GNU awkは、任意精度の数値を使うことができます。ただし、必要なライブラリがawkの実行ファイルに組み込まれている場合に限ります。awkのバージョンを確認して、"GNU MPFR"があるかどうかを見てみましょう。
$ gawk --version
GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)
...
組み込まれていれば、-Mオプションでこの機能を有効にできます。
$ gawk -M 'BEGIN {
n = 2 ^ 54
if (n == n + 1)
print "not enough precision"
else
print "OK"
}'
OK
自分のawkに-Mがない場合はどうすればよいでしょうか? その場合は、bcのように任意精度演算ができる外部プログラムを呼び出す必要があります。その方法の例は、パイプからgetlineで変数に読み込むの節を参照してください。
さらに詳しく:任意精度演算