2017-03-08 57 views
1

我使用可以正常工作的awk(減去Time_res-Time_req來查找滯後)減去大數字,但無法在python中執行相同操作。在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 
+7

585719是正確答案。 awk是錯的,python是對的。 –

+0

像@ juanpa.arrivillaga說的是正確的操作:S – Tzomas

+0

有關使用大數字的更多信息:http://stackoverflow.com/questions/538551/handling-very-large-numbers-in-python –

回答

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

gawk你需要指定要使用的BIGNUM包(如果gawk與鏈接到該包編譯):

$ gawk -M 'BEGIN{print 1455594303469326836 - 1455594303468741117}' 
585719 

(您也可以爲相同的功能,gawk -Mgawk --bignum 'prog'

如果沒有-M開關,您可以通過將字符串添加0將輸入轉換爲整數來查看溢出。注意第2欄是不一樣的,第一:

$ 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浮點運算。所有的POSIX awk算法(或沒有bignum的gawk)都是用IEEE雙精度完成的,這個精度會隨着您輸入的大小而溢出。

+1

除此之外,OP的整數需要62位,而IEEE 754只提供53位的精度。它寫在哪裏,但awk使用雙精度?我用於OS X和NetBSD的awk手冊頁沒有提到這一點。 –

+0

我主要依靠GNU文檔:[POSIX awk使用雙精度浮點數](https://www.gnu.org/software/gawk/manual/html_node/Computer-Arithmetic.html)和[默認,gawk使用它運行的系統硬件提供的雙精度浮點值。](https://www.gnu.org/software/gawk/manual/gawk.html#MPFR-features) – dawg

+0

但是OpenGroup的[數值完全等於整數的值(請參閱從ISO C標準派生的概念)應該通過等同於對sprintf函數的調用(參見字符串函數)將字符串轉換爲字符串「%d」](http://pubs.opengroup.org/onlinepubs/9699919799/) – dawg