《Fluent Python》 -- 一個關於memoryview例子的理解過程

近日,在閱讀《Fluent Python》的第2.9.2節時,有一個關於內存視圖的例子,當時看的只知其一;不知其二,後來查了一些資料,如今總結一下,以備後續查詢;html

示例複述

添加了一些額外的代碼,便於更好理解memoryviewpython

>>> import array
>>> numbers = array.array('h', [-2, -1, 0, 1, 2])
>>> memv = memoryview(numbers)
>>> len(memv)
5
>>> memv[0]
-2
>>> memv_oct = memv.cast('B')
>>> memv_oct
<memory at 0x10869d7c8>
>>> memv_oct.tolist()
[254, 255, 255, 255, 0, 0, 1, 0, 2, 0]
>>> memv.tolist()
[-2, -1, 0, 1, 2]
>>> memv_oct[5] = 4
>>> numbers
array('h', [-2, -1, 1024, 1, 2])
>>> memv.tolist()
[-2, -1, 1024, 1, 2]
>>> memv_oct.tolist()
[254, 255, 255, 255, 0, 4, 1, 0, 2, 0]

個人理解和疑惑

  • nembers是一個signed short int類型的數組;
  • memv是使用上述數組建立的一個memoryview,即內存視圖,它使memv可以共享nembers數組的內存,但不須要複製裏面的內容,這使得memv也可以訪問和操做numbers數組的元素;memv[0] # -2也就能夠理解了。
  • memv.cast('B')memv轉換成一個unsigned char int的新memoryview,並返回給memv_oct
  • memv_oct.tolist()的元素比原始數組多了一倍:
  • memv_oct[5] = 4signed short int類型的0的高字節賦值成4;在二進制的層面下看,即0000 0000 0000 0000轉換成了0000 0000 0010 0000,十進制也就是1024;
  • 同時,咱們也能夠看到memv.tolist()也隨着numbers改變了。更能說明memoryview只是對同一塊數據的進行不一樣形式的表達;

解惑

正整數的狀況能夠理解,負整數的狀況就理解不了,這說明正負整數在內存中的存儲形式是不同的。有了方向咱們就直接搜一下吧。編程

  • signed short int類型的原碼最高位表示正負,0表明正數,1表明負數。
  • 它們內存中是以補碼的形式存儲的,其中正數的補碼和原碼相同;負數的補碼,是其原碼除符號位(即最高位)外,其他所有取反,再加1;
  • signed short int類型的-2,其原碼爲0100 0000 0000 0001,除符號位取反,爲1011 1111 1111 1111,再加1,爲0111 1111 1111 1111。當以unsigned char int類型讀出來的時候,就成了254 255了;-1亦是同理,即255 255

總結

其實這都是《計算機組成原理》的基本知識,只是當咱們習慣了使用一些高級編程語言的時候,對於這些底層的東西就不那麼敏感了。數組

相關文章
相關標籤/搜索