为什么awk会产生不同的除零结果,我该如何测试呢?

Lad*_*ada 2 error-handling awk divide-by-zero

在mawk中除以零时我得到六个不同的结果:

$ 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
Run Code Online (Sandbox Code Playgroud)

我得到每个案例的"成功"退出代码.

  1. 为什么会这样?
  2. 我能做些什么呢?在进行除法之前,我是否总是必须检查零除数?还是有办法可以依赖awk的错误处理和退出代码?

mr.*_*tic 5

我猜你正在使用mawk,没有awk,nawk或者gawk有这种行为,这些行为不支持除零.

你的答案是+inf正无穷大,nan"非数字"和-inf负无穷大,都是预期的.这些仅在打印浮动时输出,即%.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
Run Code Online (Sandbox Code Playgroud)

当您使用"%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
Run Code Online (Sandbox Code Playgroud)

如果使用已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
Run Code Online (Sandbox Code Playgroud)

(虽然没有记录,但它可能不是你应该依赖的东西).