我使用awk减去大数字,它工作正常(减去Time_res-Time_req来查找滞后),但是在python中无法做同样的事情。
ID Time_req Time_res lag
0 3000002 1455594303468741117 1455594303469326836 585728
为什么输出低于此值?
>>> 1455594303469326836 - 1455594303468741117
585719
and not 585728
我甚至尝试过
>>> long(1455594303469326836) - long(1455594303468741117)
585719L #still wrong
答案 0 :(得分:1)
要在awk中进行大量(任意精度)数学运算,您需要gawk -M
:
$ awk 'BEGIN{print 1455594303469326836 - 1455594303468741117}'
585728
$ awk -M 'BEGIN{print 1455594303469326836 - 1455594303468741117}'
585719
$ awk --version | head -2
GNU Awk 4.1.4, API: 1.1 (GNU MPFR 3.1.5, GNU MP 6.1.2)
Copyright (C) 1989, 1991-2016 Free Software Foundation.
有关详细信息,请参阅https://www.gnu.org/software/gawk/manual/gawk.html#MPFR-features。
答案 1 :(得分:1)
对于gawk
,您需要指定要使用bignum包(如果使用该包的链接编译gawk
):
$ gawk -M 'BEGIN{print 1455594303469326836 - 1455594303468741117}'
585719
(您也可以gawk --bignum 'prog'
执行与gawk -M
相同的功能)
如果没有-M
开关,您可以通过将0
添加到字符串,将输入转换为整数来查看溢出。注意第二列与第一列不同:
$ echo "1455594303469326836 1455594303468741117" | awk '{print $1 " => " $1+0,ORS $2 " => " $2+0}'
1455594303469326836 => 1455594303469326848
1455594303468741117 => 1455594303468741120
VS
$ echo "1455594303469326836 1455594303468741117" | awk -M '{print $1 " => " $1+0,ORS $2 " => " $2+0}'
1455594303469326836 => 1455594303469326836
1455594303468741117 => 1455594303468741117
由于IEEE 754双精度对于尾数具有53位精度(可用于直到该大小的精确整数表示),因此对于大小超过53位的整数,它们开始失去精确的表示能力:
$ awk 'BEGIN{print 2**53, 2**53+1}'
9007199254740992 9007199254740992
^ ^ not +1 in least significant digit
$ awk -M 'BEGIN{print 2**53, 2**53+1}'
9007199254740992 9007199254740993
^ ^ fixed...
您的输入需要61位才能准确表示(或符号位为62位),因此您无法表示输入的最低有效位。
选项的
如果您没有gawk
bignum选项,则可以将perl
与BigNum一起使用:
$ perl -Mbignum -E 'say 1455594303469326836 - 1455594303468741117'
585719
蟒:
$ python -c 'print 1455594303469326836 - 1455594303468741117'
585719
bc:
$ echo "1455594303469326836 - 1455594303468741117" | bc
585719
红宝石:
$ ruby -e "puts 1455594303469326836 - 1455594303468741117"
585719
但是基本的POSIX awk - 没有arbitrarily precision integer或非IEEE 754浮点数学的bueno。 POSIX awk(或没有bignum的gawk)中的所有算术都是使用IEEE双精度完成的,它会随着您输入的大小而溢出。