日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

Python 的整數與 Numpy 的數據溢出

系統 1800 0
? Python貓 ” ,一個值得加星標的 公眾號
某位 A 同學發了我一張截圖,問為何結果中出現了負數?

看了圖,我第一感覺就是數據溢出了。 數據超出能表示的最大值,就會出現奇奇怪怪的結果。

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

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

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

最后,經過學習群里的一番討論,我才終于明白是怎么回事,所以本文把相關知識點做個梳理。

在開始之前,先總結一下上圖會引出的話題:
  • Python 3 中整數的上限是多少? Python 2 呢?

  • Numpy 中整數的上限是多少? 整數溢出該怎么辦?
對于第一個問題,兩個版本的 Python 有所區別。先看看 Python 2,它有兩種整數:
  • 一種是短整數,也即常說的整數,用 int 表示,有個內置函數 int()。其大小有限,可通過 sys.maxint() 查看(取決于平臺是 32 位還是 64 位)
  • 一種是長整數,即大小無限的整數,用 long 表示,有個內置函數 long()。寫法上是在數字后面加大寫字母 L 或小寫的 l,如 1000L

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

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

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

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

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

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

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

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

由于它是 C 語言實現,在整數表示上,用的是 C 語言的規則,也就是會區分整數和長整數。

有一種方式可查看:

                
                  import?numpy?as?np

a?=?np.arange(2)
type(a[0])

#?結果:numpy.int32

                
              

也就是說它默認的整數 int 是 32 位,表示范圍在 -2147483648 ~ 2147483647。

對照前文的截圖,里面只有兩組數字相乘時沒有溢出:100007*4549、100012*13264,其它數據組都溢出了,所以出現奇怪的負數結果。

Numpy 支持的數據類型要比 Python 的多,相互間的區分界限很多樣:

Python 的整數與 Numpy 的數據溢出_第3張圖片
截圖來源: https://www.runoob.com/numpy/numpy-dtype.html

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

                
                  import?numpy?as?np

q?=?[100000]
w?=?[500000]

#?一個溢出的例子:
a?=?np.array(q)
b?=?np.array(w)
print(a*b)??#?產生溢出,結果是個奇怪的數值

#?一個解決的例子:
c?=?np.array(q,?dtype='int64')
d?=?np.array(w,?dtype='int64')
print(c*d)?#?沒有溢出:[50000000000]

                
              

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

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

640?

作者簡介: 豌豆花下貓,生于廣東畢業于武大,現為蘇漂程序員,有一些極客思維,也有一些人文情懷,有一些溫度,還有一些態度。

往期文章,推薦閱讀:

為什么要翻譯?值得堅持下去么?

Python 之父的解析器系列之四:可視化 PEG 解析

用 Python 實現簡易 Web 服務器

遇見一只黑貓,她說程序員都是騙子

Python 的整數與 Numpy 的數據溢出_第4張圖片

告訴朋友們,我在看 640?wx_fmt=png

更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 宁远县| 徐闻县| 淮滨县| 岳西县| 凤庆县| 白沙| 会同县| 枝江市| 岗巴县| 开江县| 安陆市| 繁峙县| 微博| 郧西县| 龙井市| 阿克苏市| 监利县| 泸定县| 蛟河市| 富顺县| 孟连| 蒙阴县| 古蔺县| 喜德县| 铜梁县| 读书| 招远市| 淮南市| 全椒县| 苏州市| 彭泽县| 济源市| 瓦房店市| 白玉县| 烟台市| 邮箱| 兖州市| 进贤县| 浦东新区| 黑山县| 高陵县|