目录
楔子
int实例对象的底层实现
小整数对象池
整数运算
整数的大小比较
整数的相加
整数的相减
小结

楔子
这次我们来分析一下Python中的整数是如何实现的,我们知道Python中的整数是不会溢出的,换句话说,它可以计算无穷大的数。只要你的内存足够,它就能计算,但是对于C来说显然是不行的,可Python底层又是C实现的,那么它是怎么做到整数不会溢出的呢?
既然想知道答案,那么看一下Python中的整型在底层是怎么定义的就行了。
int实例对象的底层实现
Python中的整数底层对应的结构体是PyLongObject,它位于longobject.h中。
//longobject.h typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */ //longintrepr.h struct _longobject { PyObject_VAR_HEAD digit ob_digit[1]; }; //合起来可以看成 typedef struct { PyObject_VAR_HEAD digit ob_digit[1]; } PyLongObject; //如果把这个PyLongObject更细致的展开一下就是 typedef struct { Py_ssize_t ob_refcnt; //引用计数 struct _typeobject *ob_type; //类型 Py_ssize_t ob_size; //维护的元素个数 digit ob_digit[1]; //digit类型的数组,长度为1 } PyLongObject;
讯享网
别的先不说,就冲里面的ob_size我们就可以思考一番。首先Python中的整数有大小、但应该没有长度的概念吧,那为什么会有一个ob_size呢?从结构体成员来看,这个ob_size指的应该就是ob_digit数组的长度,而这个ob_digit数组显然只能是用来维护具体的值了。而数组的长度不同,那么对应的整数占用的内存也不同。所以答案出来了,整数虽然没有我们生活中的那种长度的概念,但它是个变长对象,因为不同的整数占用的内存可能是不一样的。
因此这个ob_size它指的是底层数组的长度,因为Python中整数对应的值在底层是使用数组来存储的。尽管它没有字符串、列表那种长度的概念,或者说无法对整型使用len方法,但它是个变长对象。
那么下面的重点就在这个ob_digit数组了,我们要从它的身上挖掘信息,看看Python中整数对应的值(比如123),是怎么放在这个数组里面的。不过首先我们要看看这个digit是个什么类型,它同样定义在longintrepr.h中
讯享网//PYLONG_BITS_IN_DIGIT是一个宏,如果你的机器是64位的,那么它会被定义为30,32位机器则会被定义为15 //至于这个宏是做什么的我们先不管 #if PYLONG_BITS_IN_DIGIT == 30 typedef uint32_t digit; // ... #elif PYLONG_BITS_IN_DIGIT == 15 typedef unsigned short digit; // ... #endif
而我们的机器现在基本上都是64位的,所以PYLONG_BITS_IN_DIGIT会等于30,因为digit等价于uint32_t(unsigned int),所以它是一个无符号32位整型。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/58275.html