自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Python 的整數(shù)與 Numpy 的數(shù)據(jù)溢出

開發(fā) 后端
經(jīng)過學(xué)習(xí)群里的一番討論,我才終于明白是怎么回事,所以本文把相關(guān)知識點做個梳理。一起來看看吧。

 [[411683]]

某位 A 同學(xué)發(fā)了我一張截圖,問為何結(jié)果中出現(xiàn)了負(fù)數(shù)?

看了圖,我第一感覺就是數(shù)據(jù)溢出了。數(shù)據(jù)超出能表示的最大值,就會出現(xiàn)奇奇怪怪的結(jié)果。

然后,他繼續(xù)發(fā)了張圖,內(nèi)容是 print(100000*208378),就是直接打印上圖的 E[0]*G[0],結(jié)果是 20837800000,這是個正確的結(jié)果。

所以新的問題是:如果說上圖的數(shù)據(jù)溢出了,為何直接相乘的數(shù)卻沒有溢出?

由于我一直忽視數(shù)據(jù)的表示規(guī)則(整型的上限是多少?),而且對 Numpy 了解不多,還錯看了圖中結(jié)果,誤以為每一個數(shù)據(jù)都是錯誤的,所以就解答不出來。

最后,經(jīng)過學(xué)習(xí)群里的一番討論,我才終于明白是怎么回事,所以本文把相關(guān)知識點做個梳理。

在開始之前,先總結(jié)一下上圖會引出的話題:

  •  Python 3 中整數(shù)的上限是多少?Python 2 呢?
  •  Numpy 中整數(shù)的上限是多少?整數(shù)溢出該怎么辦?

對于第一個問題,兩個版本的 Python 有所區(qū)別。先看看 Python 2,它有兩種整數(shù):

  •  一種是短整數(shù),也即常說的整數(shù),用 int 表示,有個內(nèi)置函數(shù) int()。其大小有限,可通過sys.maxint() 查看(取決于平臺是 32 位還是 64 位)
  •  一種是長整數(shù),即大小無限的整數(shù),用 long 表示,有個內(nèi)置函數(shù) long()。寫法上是在數(shù)字后面加大寫字母 L 或小寫的 l,如 1000L

當(dāng)一個整數(shù)超出短整數(shù)范圍時,它會自動采用長整數(shù)表示。舉例,打印 2**100 ,結(jié)果會在末尾加字母 L 表示它是長整數(shù)。

但是到了 Python 3,情況就不同了:它僅有一種內(nèi)置的整數(shù),表示為 int,形式上是 Python 2 的短整數(shù),但實際上它能表示的范圍無限,行為上更像是長整數(shù)。無論多大的數(shù),結(jié)尾都不需要字母 L 來作區(qū)分。

也就是說,Python 3 整合了兩種整數(shù)表示法,用戶不再需要自行區(qū)分,全交給底層按需處理。

理論上,Python 3 中的整數(shù)沒有上限(只要不超出內(nèi)存空間)。這就解釋了前文中直接打印兩數(shù)相乘,為什么結(jié)果會正確了。

PEP-237(Unifying Long Integers and Integers)中對這個轉(zhuǎn)變作了說明。它解釋這樣做的目的:

這會給新的 Python 程序員(無論他們是否是編程新手)減少一項上手前要學(xué)的功課。

Python 在語言運用層屏蔽了很多瑣碎的活,比如內(nèi)存分配,所以,我們在使用字符串、列表或字典等對象時,根本不用操心。整數(shù)類型的轉(zhuǎn)變,也是出于這樣的便利目的。(壞處是犧牲了一些效率,在此就不談了)

回到前面的第二個話題:Numpy 中整數(shù)的上限是多少?

由于它是 C 語言實現(xiàn),在整數(shù)表示上,用的是 C 語言的規(guī)則,也就是會區(qū)分整數(shù)和長整數(shù)。

有一種方式可查看: 

  1. import numpy as np  
  2. a = np.arange(2)  
  3. type(a[0])  
  4. # 結(jié)果:numpy.int32 

也就是說它默認(rèn)的整數(shù) int 是 32 位,表示范圍在 -2147483648 ~ 2147483647。

對照前文的截圖,里面只有兩組數(shù)字相乘時沒有溢出:100007*4549、100012*13264,其它數(shù)據(jù)組都溢出了,所以出現(xiàn)奇怪的負(fù)數(shù)結(jié)果。

Numpy 支持的數(shù)據(jù)類型要比 Python 的多,相互間的區(qū)分界限很多樣:

截圖來源:https://www.runoob.com/numpy/numpy-dtype.html

要解決整數(shù)溢出,可通過指定 dtype 的方式: 

  1. import numpy as np  
  2. q = [100000]  
  3. w = [500000]  
  4. # 一個溢出的例子:  
  5. a = np.array(q)  
  6. b = np.array(w)  
  7. print(a*b)  # 產(chǎn)生溢出,結(jié)果是個奇怪的數(shù)值  
  8. # 一個解決的例子:  
  9. c = np.array(q, dtypeint64 )  
  10. d = np.array(w, dtypeint64 )  
  11. print(c*d) # 沒有溢出:[50000000000] 

好了,前面提出的問題就回答完了。

來作個結(jié)尾吧:

  •  Python 3 極大地簡化了整數(shù)的表示,效果可表述為:整數(shù)就只有一種整數(shù)(int),沒有其它類型的整數(shù)(long、int8、int64 之類的)
  •  Numpy 中的整數(shù)類型對應(yīng)于 C 語言的數(shù)據(jù)類型,每種“整數(shù)”有自己的區(qū)間,要解決數(shù)據(jù)溢出問題,需要指定更大的數(shù)據(jù)類型(dtype) 

 

責(zé)任編輯:龐桂玉 來源: 機(jī)器學(xué)習(xí)算法與Python學(xué)習(xí)
相關(guān)推薦

2021-08-19 16:56:37

Python內(nèi)存開發(fā)

2016-09-19 10:14:54

PythonNumpy數(shù)據(jù)

2015-03-30 11:18:50

內(nèi)存管理Android

2009-09-04 10:37:50

Java堆棧溢出

2024-06-06 09:08:14

NumPyPython數(shù)據(jù)分析

2010-09-25 11:23:15

Java內(nèi)存泄露

2023-11-23 08:58:45

PythonNumPy

2022-06-27 08:31:29

數(shù)據(jù)溢出無符號

2021-05-22 09:44:21

PythonNumpy數(shù)組Python矩陣

2012-05-15 02:04:22

JVMJava

2024-03-11 08:22:40

Java內(nèi)存泄漏

2020-07-09 10:29:29

數(shù)據(jù)中心IT技術(shù)

2020-11-13 09:31:44

分治算法運算

2020-11-05 11:30:46

PythonNumPy數(shù)組

2021-12-17 08:27:55

NumpyPython 機(jī)器學(xué)習(xí)

2020-12-15 10:14:47

NumPynanPython

2019-10-25 15:44:10

Pythonnumpy數(shù)組分析

2022-02-18 12:24:39

PythonNumpy Arra大數(shù)據(jù)

2019-09-11 14:34:13

排序算法數(shù)據(jù)科學(xué)

2024-09-09 09:41:03

內(nèi)存溢出golang開發(fā)者
點贊
收藏

51CTO技術(shù)棧公眾號