3 python的数值在内存中如何存储

python的数值在内存中如何存储

 

在Python中,数值在内存中的存储方式取决于数值的类型和大小,以及Python的版本。Python使用固定的字节数来表示整数类型,并且对于浮点数,通常使用双精度(64位)或者扩展精度(128位)的浮点表示。

整数的存储方式: 对于较小的整数,Python通常使用一个机器字长来存储它们,例如,在32位机器上,小整数通常使用32位来存储。对于较大的整数,Python使用了一种称为GMPY的机制,它使用动态大小的字节数组来存储。

浮点数的存储方式: Python使用IEEE 754标准来存储浮点数,对于64位的浮点数,Python使用1位作为符号位(E),11位作为指数位(M),52位作为尾数位(M)。

下面是一个简单的例子,演示了如何在Python中查看数值的内存表示:

1
2
3
4
5
6
7
8
9
10
11
12
import sys
  
def view_bytes(number, bits):
    return bin(int.from_bytes(number.to_bytes(bits // 8, sys.byteorder), 'little'))[2:]
  
# 整数示例
i = 10
print(f"The binary representation of {i} is: {view_bytes(i, 64)}")
  
# 浮点数示例
f = 3.14
print(f"The binary representation of {f} is: {view_bytes(f, 64)}")

  

这段代码使用了sys.byteorder来确定字节顺序(大端或小端),int.from_bytes和int.to_bytes来转换整数为字节序列,并使用bin函数转换为二进制字符串。对于浮点数,它使用了相同的方法,但是浮点数需要先转换为一个双精度的浮点数。

注意:这个方法只适用于显示数值的二进制表示,并不能直接显示Python内部如何存储数值的细节。实际上,Python的内部实现可能会根据平台和Python版本的不同而有所差异。

 

 

偶然间看到float的取值范围是-3.4*10^38到3.4*10^38,然后有效位数是6位或者7位(和编译器有关),突发奇想,想知道float和double的取值范围是如何计算出来的,了解了一下,大概做个总结。

 

首先说一下Float

 

1.Float的内存结构
首先我们需要了解一下float的内存结构,弄清楚它在内存中是如何存放的。

 

float和整形(int等)存放的方式不一样,是以指数方式(科学计数法)的方式存储的。分为三个部分。符号位,指数部分,尾数部分,float占4个字节,总共32位,其中符号位占一位,指数占8位,尾数占23位,数字9.25的存储结构如下图所示:

 

 

 

 

符号位就是表示当前变量的正负,1正0负

 

这个例子的表示的float的值是:1.00101 * 2^3,也就是 1001.01,转换成10进制就是9+

 

 

 

 

=9.25,具体是为什么呢,可以往下看

 

指数部分
 float的指数位没有符号,在内存中将指数+127存储。

 

图中指数部分是1000 0010,对应的十进制数是130,实际上的指数值需要减去127,也就是3,所以例子中对应的指数就是3,

 

所以去掉一个最大值,一个最小值,指数表达的范围是:[-126,127]

 

尾数部分
尾数部分占23位,但是实际上是24位1第一位1被省略,例子中9.25对应的二进制数是1001.01,

 

 

 

 

,1001.01可以写成

 

 

 

。我们可以发现,只要我们要存储的数值不为0,任何数都可以写成1.xxxxx 

 

 

 

 

,所以我们第一位数是可以省略的,不用存储,尾数部分存储的就是小数点后面的内容,小数点也不用存储。我们存在内存中的数就是0010 1000 0000 0000.........(总共23位尾数)

 

如果要float变量的值为0,那就让尾数和指数全为0,以此来表示0,这是一种特殊情况。

 

2.float的取值范围分析
所以float的最大值最小值怎么出来呢?

 

 

 

 

        指数全1的情况(255-127)为了表示特殊的值被用掉了,所以指数最大是254-127=127,尾数省略1和小数点,所以为了使尾数最大,取全1,这时候尾数 = 

 

 

 

 

,这个数非常接近2,所以最后的值就是2*2^127 = 2*1.7014 E38,大概就是3.4E38左右,

 

最小就是将符号位变成1,表示负数,其他没有任何区别。

 

double的话指数长度为11位,尾数长度为52位,存储原理是一样的。

 

 

复制代码
import struct

# 定义一个双精度浮点数
value = 123.456

# 将浮点数转换为字节
bytes_value = struct.pack('d', value)

# 打印字节表示
print(bytes_value)
复制代码

 

posted @   szmtjs10  阅读(120)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
历史上的今天:
2022-03-19 第1章 数据类型 第4节 JavaScript字符类型
点击右上角即可分享
微信分享提示