34

我想awk使用整数除法将两个数字相除,即截断结果。例如

k = 3 / 2
print k

应该打印1

根据手册

分配; 因为 awk 中的所有数字都是浮点数,所以结果不会四舍五入为整数

是否有任何解决方法来获取整数值?

原因是我想获取具有整数索引 [0 到 num-1]的数组的中间元素。

4

3 回答 3

53

使用该int函数获取结果的整数部分,向 0 截断。这将生成最接近结果的整数,位于结果和 0 之间。例如,int(3/2)是 1,int(-3/2)是 -1。

资料来源:AWK 手册 - 数值函数

于 2013-02-13T16:28:53.593 回答
12

在简单的情况下,您可以安全地使用int()which 截断为零1

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

这真的很尴尬,又长又慢,……但安全又便携。


1POSIX 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表达式中指定为双精度浮点数。
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
    

阅读更多关于花车如何工作的信息:

  1. Stack Overflow 标签wiki

  2. 维基百科文章浮点

  3. GNU awk 任意精度算术- 包含有关特定实现和一般知识的信息

于 2014-02-19T00:12:02.383 回答
7

安全快速的 awk 整数除法可以通过以下方式完成:

q=(n-n%d)/d+(n<0)
于 2014-10-04T18:41:19.603 回答