Python整数与Numpy数据溢出问题解决
Python / 管理员 发布于 7年前 400
某位 A 同学发了我一张截图,问为何结果中出现了负数?
看了图,我第一感觉就是数据溢出了。数据超出能表示的最大值,就会出现奇奇怪怪的结果。
然后,他继续发了张图,内容是 print(100000*208378),就是直接打印上图的 E[0]*G[0],结果是 20837800000,这是个正确的结果。
所以新的问题是:如果说上图的数据溢出了,为何直接相乘的数却没有溢出?
由于我一直忽视数据的表示规则(整型的上限是多少?),而且对 Numpy 了解不多,还错看了图中结果,误以为每一个数据都是错误的,所以就解答不出来。
最后,经过学习群里的一番讨论,我才终于明白是怎么回事,所以本文把相关知识点做个梳理。
在正式开始之前,先总结一下上图会引出的话题:
关于第一个问题,先看看 Python 2,它有两种整数:
当一个整数超出短整数范围时,它会自动采用长整数表示。举例,打印 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 npa = 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 npq = [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]
好了,前面提出的问题就回答完了。来作个结尾吧:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号