2

mawkでゼロ除算すると、6つの異なる結果が得られます。

$ echo | awk '{print -1/0 }' ; echo $?
-inf
0
$ echo | awk '{print 0/0 }' ; echo $?
-nan
0
$ echo | awk '{print 1/0 }' ; echo $?
inf
0
$ echo | awk '{printf ("%i\n", -1/0) }' ; echo $?
-2147483647
0
$ echo | awk '{printf ("%i\n", 0/0) }' ; echo $?
-2147483647
0
$ echo | awk '{printf ("%i\n", 1/0) }' ; echo $?
2147483647
0

ケースごとに「成功」​​終了コードを取得します。

  1. なぜこれが起こるのですか?
  2. 私はそれについて何ができますか?除算を行う前に常にゼロ因子をチェックする必要がありますか、それともawkのエラー処理と終了コードに依存する方法はありますか?
4

3 に答える 3

6

mawkを使用している、 を使用していないawknawkまたはこの動作をしていると思いますgawk。これらではゼロ除算はサポートされていません。

あなたの答えは+inf、正の無限大、nan「数ではない」、および-inf負の無限大であり、すべて期待どおりです。これらは、 floatを出力する場合にのみ出力されます。つまり、%.6gこれがデフォルトですOFMT(数値の出力に使用されるデフォルトの形式)。

$ mawk 'BEGIN {printf ("%i\n", 1/0) }'
2147483647
$ mawk 'BEGIN {printf ("%f\n", 1/0) }'
inf
$ gawk 'BEGIN {printf ("%f\n", 1/0) }'
gawk: fatal: division by zero attempted

「%i」で明示的に印刷すると、代わりに +HUGE または -HUGE が得られます。これは int (この場合は 32 ビット符号付き) に変換され、+ または - (2^31-1) として印刷されます。

通常は常にゼロ除算をチェックし、理想的には式を再編成してチェックする回数を最小限に抑えることです。ゼロ除算は awk の他の実装を単純に終了させます。

ビルド時mawkに、C 数学ライブラリの機能が検出されます。

$ ./configure
[...]
checking handling of floating point exceptions
    division by zero does not generate an exception
    overflow does not generate an exception
    math library supports ieee754

NOINFO_SIGFPE以下を定義してビルドすると、「標準」の動作を得ることができます。

$ ./configure CFLAGS="-DNOINFO_SIGFPE"
$ make clean && make
$ ./mawk 'BEGIN {printf ("%f\n", 1/0) }'
mawk: run time error: division by zero
    FILENAME="" FNR=0 NR=0

(これは文書化されていませんが、信頼できるものではないかもしれません)。

于 2013-01-29T12:30:18.233 に答える
3

さまざまなAWK「方言」を試した後、次の結論に達しました。

しようとしているawk

echo | awk '{print -1/0 }' ; echo $?

私は得ています:

awk: (FILENAME=- FNR=1) fatal: division by zero attempted
2

しようとしているgawk

echo | gawk '{print -1/0 }' ; echo $?

私は得ています:

gawk: (FILENAME=- FNR=1) fatal: division by zero attempted
2

しようとしているmawk

echo | mawk '{print -1/0 }' ; echo $?

私は得ています:

-inf
0

私があなただったら、あなたの「デフォルトの方言」 ( awk --version) を特定しようとし、別の方言を使用してgawk、何が起こったかを理解するために終了ステータスを読み取ろうとします。

PS: Ubuntu 11.10 を実行しています。

PS: 私の場合awkは のエイリアスですgawk

于 2013-01-29T11:55:57.957 に答える