Awk:为什么取整数字不';你不能用射程吗?

Awk:为什么取整数字不';你不能用射程吗?,awk,floating-point,range,rounding,Awk,Floating Point,Range,Rounding,试着理解为什么下面的代码会打印我想要的0-30范围 awk 'BEGIN{n=300;k=sprintf("%.0f",n/10);x=k*1;for (i=0;i<=x;i++) print i}' /dev/null awk'BEGIN{n=300;k=sprintf(“%.0f”,n/10);x=k*1;对于(i=0;i),从文档中可以清楚地看到,sprintf返回一个字符串类型,您需要在循环期间将其转换为整数 awk 'BEGIN{n=300;k=sprintf("%.0f",n

试着理解为什么下面的代码会打印我想要的0-30范围

awk 'BEGIN{n=300;k=sprintf("%.0f",n/10);x=k*1;for (i=0;i<=x;i++) print i}' /dev/null
awk'BEGIN{n=300;k=sprintf(“%.0f”,n/10);x=k*1;对于(i=0;i),从文档中可以清楚地看到,
sprintf
返回一个字符串类型,您需要在循环期间将其转换为整数

awk 'BEGIN{n=300;k=sprintf("%.0f",n/10);for (i=0;i<=k+0;i++) print i}' /dev/null
#                                                   ^^^^ adding +0 casts any string type to an 
#                                                       numeric type in awk

你希望sprintf()能为你做什么?它真正做的只是将你想要的数字转换成一个字符串,这样后面的比较是基于字符串的,而不是基于数字的,这就是为什么你会遇到问题,因为字符串
“4”
比字符串
“30”大
。顺便说一句,行尾不需要/dev/null。只需要:

awk 'BEGIN{n=300;k=n/10;for (i=0;i<=k;i++) print i}'
请注意,对于正数
int(x)
总是向下舍入,而
int(x+0.5)
总是向上舍入,而
sprintf(“%0.f”,x)
总是向最近的偶数舍入。对于负数也要这样做:

$ awk 'BEGIN{x=1; print x, "down:", int(x<0 ? x-0.5 : x), "up:", int(x<0 ? x : x+0.5)}'
1 down: 1 up: 1
$ awk 'BEGIN{x=0.5; print x, "down:", int(x<0 ? x-0.5 : x), "up:", int(x<0 ? x : x+0.5)}'
0.5 down: 0 up: 1
$ awk 'BEGIN{x=0; print x, "down:", int(x<0 ? x-0.5 : x), "up:", int(x<0 ? x : x+0.5)}'
0 down: 0 up: 0
$ awk 'BEGIN{x=-0.5; print x, "down:", int(x<0 ? x-0.5 : x), "up:", int(x<0 ? x : x+0.5)}'
-0.5 down: -1 up: 0
$ awk 'BEGIN{x=-1; print x, "down:", int(x<0 ? x-0.5 : x), "up:", int(x<0 ? x : x+0.5)}'
-1 down: -1 up: -1

$awk'开始{x=1;打印x,“向下:”,int(xThanks!这是一个比创建另一个变量更好的解决方案。如果你的问题是关于如何对一个数字进行舍入,那么在示例中使用一个不需要舍入的数字是有意义的。
300/10
30
-不涉及舍入。想象一下,对数字进行舍入
0.5-2**-54
,而对r正数可以实现为
int(x+0.5)
,它将把这个数字四舍五入到1,而它应该是0。我找不到任何其他符合这个标准的数字。谢谢。在我的gawk版本中,至少
0.4999999999991
生成正确的输出,但是
0.49999999992
将四舍五入到1,而不是降到0。现在,我必须决定是否需要考虑一个实际上,使用round()来处理这种情况,因为数字本身可能是浮点计算的产物,而浮点计算本身涉及一些近似值。嗯……0.4999999999992在数字上相当于标准IEEE二进制文件中的0.5 64
awk 'BEGIN{n=300;k=n/10;for (i=0;i<=k;i++) print i}'
$ awk 'BEGIN{x=6.5; print x, int(x), sprintf("%.0f",x), int(x+0.5)}'
6.5 6 6 7

$ awk 'BEGIN{x=7.5; print x, int(x), sprintf("%.0f",x), int(x+0.5)}'
7.5 7 8 8
$ awk 'BEGIN{x=1; print x, "down:", int(x<0 ? x-0.5 : x), "up:", int(x<0 ? x : x+0.5)}'
1 down: 1 up: 1
$ awk 'BEGIN{x=0.5; print x, "down:", int(x<0 ? x-0.5 : x), "up:", int(x<0 ? x : x+0.5)}'
0.5 down: 0 up: 1
$ awk 'BEGIN{x=0; print x, "down:", int(x<0 ? x-0.5 : x), "up:", int(x<0 ? x : x+0.5)}'
0 down: 0 up: 0
$ awk 'BEGIN{x=-0.5; print x, "down:", int(x<0 ? x-0.5 : x), "up:", int(x<0 ? x : x+0.5)}'
-0.5 down: -1 up: 0
$ awk 'BEGIN{x=-1; print x, "down:", int(x<0 ? x-0.5 : x), "up:", int(x<0 ? x : x+0.5)}'
-1 down: -1 up: -1