awk
整数除算を使用して、つまり結果を切り捨てて、 の2 つの数値を除算したいと考えています。例えば
k = 3 / 2
print k
印刷する必要があります1
説明書によると、
分割; awk のすべての数値は浮動小数点数であるため、結果は整数に丸められません。
整数値を取得するための回避策はありますか?
その理由は、整数インデックス [0 から num-1] を持つ配列の中央の要素を取得したいからです。
関数を使用して、int
0 に向かって切り捨てられた結果の整数部分を取得します。これにより、結果と 0 の間に位置する、結果に最も近い整数が生成されます。たとえば、int(3/2)
is 1、int(-3/2)
is -1 です。
出典: AWK マニュアル - 数値関数
単純なケースでは、ゼロ1int()
に向かって切り捨てられる whichを安全に使用できます。
awk 'BEGIN { print int(3 / 2) }' # prints 1
gawk 'BEGIN { print int(-3 / 2) }' # prints -1; not guaranteed in POSIX awk
ただし、 awk は常に倍精度浮動小数点数2と浮動小数点演算3を使用することに注意してください。整数と整数演算を取得できる唯一の方法は、標準expr
ユーティリティなどの外部ツールを使用することです。
awk 'BEGIN { "expr 3 / 2" | getline result; print result; }' # prints 1
これは本当に厄介な病棟で、長く、遅く、... しかし安全で移植可能です。
1 POSIX awkでは、ゼロへの切り捨ては正の引数に対してのみ保証されています: int(x) — 整数に切り捨てられた引数を返します。x>0 の場合、切り捨ては 0 に向かって行われます。 GNU awk (gawk) は、負の数に対してもゼロ方向への切り捨てを使用します: int(x) — x とゼロの間に位置し、ゼロ方向に切り捨てられた、x に最も近い整数を返します。たとえば、int(3) は 3、int(3.9) は 3、int(-3.9) は -3、int(-3) も -3 です。
2数値式は、POSIXの awk の Expressions で倍精度浮動小数点数として指定されます。
3 すべての演算は、ISO C 標準で指定されている浮動小数点演算のセマンティクスに従うものとします (ISO C 標準から派生した概念)。— POSIX awk: 算術関数
フロートを使用することを選択した場合は、フロートの癖について知り、それらを見つけて関連するバグを回避する準備ができている必要があります。いくつかの恐ろしい例:
表現できない数字:
awk 'BEGIN { x = 0.875; y = 0.425; printf("%0.17g, %0.17g\n", x, y) }'
# prints 0.875, 0.42499999999999999
丸め誤差の累積:
awk 'BEGIN{s=0; for(i=1;i<=100000;i++)s+=0.3; printf("%.10f, %d\n",s,int(s))}'
# prints 29999.9999999506, 29999
丸め誤差は比較を台無しにします:
awk 'BEGIN { print (0.1 + 12.2 == 12.3) }' # prints 0
大きさに応じて精度が低下し、無限ループが発生します。
awk 'BEGIN { for (i=10^16; i<10^16+5; i++) printf("%d\n", i) }'
# prints 10000000000000000 infinitely many times
フロートの仕組みについて詳しくは、次をご覧ください。
Stack Overflow タグ浮動小数点wiki
ウィキペディアの記事浮動小数点
GNU awk 任意精度演算– 特定の実装に関する情報と一般的な知識の両方が含まれています
安全で迅速な awk 整数除算は、次の方法で実行できます。
q=(n-n%d)/d+(n<0)