<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>source code Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/source-code/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/source-code/</link>
	<description></description>
	<lastBuildDate>Mon, 25 Nov 2019 07:19:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.8</generator>

<image>
	<url>https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/cropped-photo-32x32.jpg</url>
	<title>source code Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/source-code/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Python中的整型占多少个字节？</title>
		<link>https://zxi.mytechroad.com/blog/desgin/python%e4%b8%ad%e7%9a%84%e6%95%b4%e5%9e%8b%e5%8d%a0%e5%a4%9a%e5%b0%91%e4%b8%aa%e5%ad%97%e8%8a%82%ef%bc%9f/</link>
					<comments>https://zxi.mytechroad.com/blog/desgin/python%e4%b8%ad%e7%9a%84%e6%95%b4%e5%9e%8b%e5%8d%a0%e5%a4%9a%e5%b0%91%e4%b8%aa%e5%ad%97%e8%8a%82%ef%bc%9f/#comments</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 25 Nov 2019 06:11:06 +0000</pubDate>
				<category><![CDATA[Desgin]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[source code]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5853</guid>

					<description><![CDATA[<p>说到计算机中的整型，相信很多人都会联想到32位整型（或者int），是程序员日常生活中用的最多的一种类型。32位整型顾名思义，占用32个位也就是4个字节，取值范围−2,147,483,648~ 2,147,483,647 。C/C++中是4个字节，Java中也是4个字节，但是Python中呢？ 我们知道Python中也有int类，而且非常好用，原生支持高精度计算。但是Python中的一个整型到底占用多少字节呢？我相信绝大多数的Python程序员从未想过这一点，越是习以为常的东西越是不会在意它的存在。 在Python中，如果想要知道一个对象所占用的内存大小，只需要使用sys.getsizeof这个API就可以了。那就让我们来试一下不同的整数 [crayon-663c127c9a7a2703356589/] 从上面的小实验可以看出，一个整型最少要占24字节(0)，1开始就要占用28个字节，到了2的30次方开始要占用32个字节，而2的128次方则要占用44个字节。我们可以得到两点规律，1. 字节数随着数字增大而增大。2. 每次的增量是4个字节。 好像至此已经回答了我们的题目中的问题：Python中的整型占多少个字节？答案是：变长的（相对于int32的定长），而且最少24个字节。 你以为本文到这里就结束了吗？那你就图样图森破了。一个整型数2，居然要占用28个字节！这完全了颠覆了我的认知，我一定搞清楚为什么。 在哥们的帮助下，我找到了Python的源码。 https://github.com/python/cpython Python的官方实现是C语言，所以叫cpython。这也就意味着只要Python还在，C就会不消失。其他实现还有jython(Java), IronPython (.Net), PyPy (Python)。 第一件事情要搞清楚的是Python中int类型在cpython的名字是什么？看了半天，在 longobject.h 中发现了一个叫 PyLongObject 的结构体。然而它只是一个马甲，是 _longobject的别名。在longintrepr.h中找到了 _longobject&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/desgin/python%e4%b8%ad%e7%9a%84%e6%95%b4%e5%9e%8b%e5%8d%a0%e5%a4%9a%e5%b0%91%e4%b8%aa%e5%ad%97%e8%8a%82%ef%bc%9f/">Python中的整型占多少个字节？</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>说到计算机中的整型，相信很多人都会联想到32位整型（或者int），是程序员日常生活中用的最多的一种类型。32位整型顾名思义，占用32个位也就是4个字节，取值范围−2,147,483,648~ 2,147,483,647 。C/C++中是4个字节，Java中也是4个字节，但是Python中呢？</p>



<p>我们知道Python中也有int类，而且非常好用，原生支持高精度计算。但是Python中的一个整型到底占用多少字节呢？我相信绝大多数的Python程序员从未想过这一点，<strong>越是习以为常的东西越是不会在意它的存在</strong>。</p>



<p>在Python中，如果想要知道一个对象所占用的内存大小，只需要使用<code>sys.getsizeof</code>这个API就可以了。那就让我们来试一下不同的整数</p>



<pre class="crayon-plain-tag">print(sys.getsizeof(0))        # 24
print(sys.getsizeof(1))        # 28 
print(sys.getsizeof(2))        # 28
print(sys.getsizeof(2**15))    # 28
print(sys.getsizeof(2**30))    # 32
print(sys.getsizeof(2**128))   # 44</pre>



<p>从上面的小实验可以看出，一个整型最少要占24字节(0)，1开始就要占用28个字节，到了2的30次方开始要占用32个字节，而2的128次方则要占用44个字节。我们可以得到两点规律，1. 字节数随着数字增大而增大。2. 每次的增量是4个字节。  好像至此已经回答了我们的题目中的问题：Python中的整型占多少个字节？答案是：变长的（相对于int32的定长），而且最少24个字节。  </p>



<p>你以为本文到这里就结束了吗？那你就图样图森破了。一个整型数2，居然要占用28个字节！这完全了颠覆了我的认知，我一定搞清楚为什么。 在哥们的帮助下，我找到了Python的源码。 <a href="https://github.com/python/cpython">https://github.com/python/cpython</a>  </p>



<p>Python的官方实现是C语言，所以叫cpython。这也就意味着只要Python还在，C就会不消失。其他实现还有jython(Java), IronPython (.Net), PyPy (Python)。</p>



<p>第一件事情要搞清楚的是Python中int类型在cpython的名字是什么？看了半天，在 <a href="https://github.com/python/cpython/blob/master/Include/longobject.h">longobject.h</a> 中发现了一个叫  <code>PyLongObject</code> 的结构体。然而它只是一个马甲，是 <code>_longobject</code>的别名。在<a href="https://github.com/python/cpython/blob/master/Include/longintrepr.h">longintrepr.h</a>中找到了 <code>_longobject  </code>的定义如下：</p>



<pre class="crayon-plain-tag">struct _longobject {
     PyObject_VAR_HEAD
     digit ob_digit[1];
 };</pre>



<p>在文件的开头就看到了<code>typedef uint32_t digit;</code>，<code>digit</code>就是<code>unit32_t</code>, 每个元素占4个字节。但<code>PyObject_VAR_HEAD</code>又是什么鬼？在<a href="https://github.com/python/cpython/blob/master/Include/object.h">object.h</a>中发现了它是个宏，上面的注释倒是挺有意思的。</p>



<pre class="crayon-plain-tag">/* PyObject_VAR_HEAD defines the initial segment of all variable-size
 container objects.  These end with a declaration of an array with 1
 element, but enough space is malloc'ed so that the array actually
 has room for ob_size elements.  Note that ob_size is an element count,
 not necessarily a byte count.
 */ 
 define PyObject_VAR_HEAD      PyVarObject ob_base;</pre>



<p>等一下，<code>PyVarObject</code>又是什么？还好定义就在下面。</p>



<pre class="crayon-plain-tag">typedef struct {
     PyObject ob_base;
     Py_ssize_t ob_size; /* Number of items in variable part */
 } PyVarObject;</pre>



<p>又一层嵌套，是不是已经晕了，继续查看<code>PyObject</code>的定义，这次反而在上面了。</p>



<pre class="crayon-plain-tag">typedef struct _object {
     _PyObject_HEAD_EXTRA
     Py_ssize_t ob_refcnt;
     struct _typeobject *ob_type;
 } PyObject;</pre>



<p>有完没完啊？<code>_PyObject_HEAD_EXTRA</code>又是什么？看了一下发现它只在debug build中有定义，这里就不展开了。<code>Py_ssize_t</code>等于<code>ssize_t</code>如果有定义的话， <code>ssize_t</code>在64位的机器上就是<code>long</code>。<code>_typeobject</code>又是什么？感觉应该非常大，不然就不会用指针了。不过话说回来，既然用了指针，我又何必去关心它是什么呢？反正就是8个字节而已，指向一个内存地址。至此真相大了一个白，如果我们把structs flatten,  <code>PyLongObject</code> 定义如下：</p>



<pre class="crayon-plain-tag">struct PyLongObject {
  long ob_refcnt;                // 8 bytes
  struct _typeobject *ob_type;   // 8 bytes
  long ob_size;                  // 8 bytes
  unsigned int ob_digit[1];      // 4 bytes * abs(ob_size)
};</pre>



<p><code>ob_refcnt</code>引用计数 8个字节，<code>ob_type</code>类型信息 8个字节（指针），<code>ob_size</code>变长部分元素的个数，8个字节。<code>ob_digit</code>变长的数据部分，字节数为4*abs(<code>ob_size</code>)，<code>ob_size</code>可以为0，所以最少8+8+8=24字节，每次增量都是4 (<code>unsigned int</code>) 的倍数。这和我们之前观察到的实验结果吻合。</p>



<p>以上都是基于64位的Python，对于32位的版本，定义如下：</p>



<pre class="crayon-plain-tag">struct PyLongObject {
  int ob_refcnt;                // 4 bytes
  struct _typeobject *ob_type;  // 4 bytes
  int ob_size;                  // 4 bytes
  unsigned short ob_digit[1];   // 2 bytes * abs(ob_size)
};</pre>



<p>32位就要比64位小很多了，最少12个字节，增量为2个字节。</p>



<p>好了，今天就写到这里。相信你对整型数或者Python有了一个新的认识。下面一篇我们会将会介绍整型数在Python中的表示和计算。</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/desgin/python%e4%b8%ad%e7%9a%84%e6%95%b4%e5%9e%8b%e5%8d%a0%e5%a4%9a%e5%b0%91%e4%b8%aa%e5%ad%97%e8%8a%82%ef%bc%9f/">Python中的整型占多少个字节？</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/desgin/python%e4%b8%ad%e7%9a%84%e6%95%b4%e5%9e%8b%e5%8d%a0%e5%a4%9a%e5%b0%91%e4%b8%aa%e5%ad%97%e8%8a%82%ef%bc%9f/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
