Python 的整數與 Numpy 的數據溢出

来源:https://www.cnblogs.com/pythonista/archive/2019/09/10/11503117.html
-Advertisement-
Play Games

某位 A 同學發了我一張截圖,問為何結果中出現了負數? 看了圖,我第一感覺就是數據溢出了。數據超出能表示的最大值,就會出現奇奇怪怪的結果。 然後,他繼續發了張圖,內容是 print(100000\ 208378),就是直接列印上圖的 E[0]\ G[0],結果是 20837800000,這是個正確的 ...


某位 A 同學發了我一張截圖,問為何結果中出現了負數?

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

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

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

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

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

在正式開始之前,先總結一下上圖會引出的話題:

  • Python 3 中整數的上限是多少?Python 2 呢?
  • Numpy 中整數的上限是多少?出現整數溢出該怎麼辦?

關於第一個問題,先看看 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 的多,相互間的區分界限很多樣:

截圖來源: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)

公眾號【Python貓】, 本號連載優質的系列文章,有喵星哲學貓系列、Python進階系列、好書推薦系列、技術寫作、優質英文推薦與翻譯等等,歡迎關註哦。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • range函數可創建一個整數列表。 如果需要知道當前元素在列表中的索引,推薦用enumerate代替range。 zip函數用於同時遍歷多個迭代器。 ...
  • 最近在研究SpringAOP,當然要學習AOP就要知道這麼健碩、強大的功能的背後究竟隱藏著怎樣不可告人的“秘密”?? 接下來就是查閱了許多資料詳細的研究了一下Java的代理模式,感覺還是非常非常重要的, 我們作為一個有“內涵的”程式員就更應該掌握啦!(本文需要細心、帶有審視的目光來甄別其中的內容) ...
  • 首先我們在名為MSG的服務中定義一個簡單的方法 我們需要在另一個服務中調用這個服務的方法,除了使用httpclient之外,我們還能用RestTemplate(RestTemplate是Spring提供的用於訪問Rest服務的客戶端) 第一種方式,這種方式只要指定url和返回類型即可調用,但是url ...
  • 摘要: 關於這個話題可能最多的是 和`@Transactional`一起混用,我先解釋一下什麼是代理對象內嵌調用,指的是一個代理方法調用了同類的另一個代理方法。首先在這兒我要聲明事務直接的嵌套調用除外,至於為什麼,是它已經將信息保存線上程級別了,是不是又點兒抽象,感覺吃力,可以看看我前面關於事務的介 ...
  • Dubbo 2.7.x 作為 Apache 的孵化版本,除了代碼優化之外,還新增了許多重磅的新特性,本文將會介紹其中最典型的三個新特性: 一、非同步化改造 二、三大中心改造 三、服務治理增強 一、非同步支持優化 我們知道dubbo協議本身支持三種發送請求方式: 單向發送:執行方法不需要返回結果 同步發送 ...
  • Netty簡介 Netty是一個高性能,高可擴展性的非同步事件驅動的網路應用程式框架,它極大的簡化了TCP和UDP客戶端和伺服器端網路開發。它是一個NIO框架,對Java NIO進行了良好的封裝。作為一個非同步NIO框架,Netty的所有IO操作都是非同步非阻塞的,通過Future-Listener機制, ...
  • 本人免費整理了Java高級資料,一共30G,需要自己領取;傳送門:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 運行時數據區域 JVM載執行Java程式的過程中會把它所管理的記憶體劃分為若幹個不同的數據區域。這些區域都有各自的用途,以及創建和銷毀的 ...
  • 在 python 中,數字類型主要包括整數、浮點數和複數。 1.整數 整數用來表示整數數值,即沒有小數部分的數值。在 python 中,整數包括正整數、負整數和0,並且他的位數是任意的 整數類型包括十進位整數、八進位整數、十六進位整數和二進位整數 註意 不能以0作為十進位數的開頭(0除外)。 在 p ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...