在python中使用非常大的数字

时间:2017-03-08 08:16:10

标签: python awk

我使用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

2 个答案:

答案 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双精度完成的,它会随着您输入的大小而溢出。