天天看點

微軟官方算法技巧

作者:opendotnet

一個直接操控記憶體的算法,微軟官方代碼。

先上圖:

微軟官方算法技巧

假如說要把一個資料data的二進制從右往左共count位寫入到一個長度為64bit位的記憶體裡,但是記憶體剩餘的bit位m_FreeBitsInCurrentSlot不足以容納count長度大小,那麼應該怎麼做呢?

首先,先從data裡面取出記憶體剩餘的bit位長度,寫入記憶體。再計算出data裡面剩餘的沒有寫入記憶體的bit位長度,執行個體化一個新的記憶體空間(因為上面的64bit位記憶體空間已經用完)。把計算出來的data剩餘的bit位長度,寫入到新的記憶體空間。

老規矩,先上代碼,注釋在代碼裡面:

這段代碼的意思是把8位元組也就是64bit的data的二進制從右第一位開始往左,數count位,存入到記憶體的某個位置。              data是需要被操作的數,count是需要操作的bit位數              void BitStreamWriter::Write( size_t data, UINT32 count )              {              _ASSERT(count <= BITS_PER_SIZE_T); //判斷操作的bit位數,確定小于64。因為64位系統的8位元組,最大的bit位數也就是64位。                  if(count) //如果操作的bit位數不等于0              {              // Increment it now as we change count later on              m_BitCount += count; //m_BitCount統計總共操作了多少bit位,每次進入count就持續相加。                  if( count > m_FreeBitsInCurrentSlot ) //m_FreeBitsInCurrentSlot被初始化成了64,代表八個位元組的位數.每次進入一個count,都會在在m_FreeBitsInCurrentSlot的基礎上減去count。這裡如果count需要操作的bit位數,大于了m_FreeBitsInCurrentSlot剩餘的位數。也就是說count操作的bit位數,大于8個位元組剩餘能放下的bit位數。那麼繼續如下判斷              {              if( m_FreeBitsInCurrentSlot > 0 ) //8位元組剩餘的bit位數大于0              {              _ASSERTE(m_FreeBitsInCurrentSlot < BITS_PER_SIZE_T); //確定8位元組剩餘的bit位數,小于64,也就是小于8個位元組              WriteInCurrentSlot( data, m_FreeBitsInCurrentSlot ); //這裡WriteInCurrentSlot函數的第二參數本來是count,但是這裡是m_FreeBitsInCurrentSlot,是因為上面判斷了8位元組剩餘的bit位數不能容納下count操作數的bit位數,是以這裡隻是把能容納下的,也就是剩餘的bit位數m_FreeBitsInCurrentSlot放入到記憶體。              count -= m_FreeBitsInCurrentSlot; //因為總共要放入count個操作數的bit位,在記憶體中已經放入了m_FreeBitsInCurrentSlot個bit位,那麼剩餘還沒放入的bit位就是count=count-m_FreeBitsInCurrentSlot。以便下面的操作放入              data >>= m_FreeBitsInCurrentSlot;//因為data的二進制從右向左第一位開始總共放入了m_FreeBitsInCurrentSlot個bit位數,這裡向右移動m_FreeBitsInCurrentSlot位,表示已經放入的抛棄掉,剩餘沒有放入的bit位,則放在data裡面,繼續下面放入。              }                  _ASSERTE( count > 0 );//這裡確定剩餘的沒有放入的count位不為0                  // Initialize the next slot              if( ++m_pCurrentSlot >= m_OutOfBlockSlot )//因為上面的8位元組64位已經放滿了,是以這裡從新初始化一個8位元組64位的長度記憶體位址。在裡面放資料。              {              // Get a new memory block              AllocMemoryBlock();//這裡重新初始化一個m_pCurrentSlot記憶體位址,參數count對參數data操作的結果放入的記憶體就是它m_pCurrentSlot              }                  InitCurrentSlot();//這裡執行個體化一個新的8位元組64位的位元組。也就是把m_FreeBitsInCurrentSlot指派為64              // Write the remainder              WriteInCurrentSlot( data, count ); //這個地方把剩餘的上面沒有放置進入的,這裡放入進去,count是上面所得剩餘。              m_FreeBitsInCurrentSlot -= count;//這裡的m_FreeBitsInCurrentSlot初始化的值是64,它減去放入了的count位,計算剩餘的位,以便下次操作繼續放入。              }              else //如果count操作數,小于剩餘的位數m_FreeBitsInCurrentSlot,這裡直接放入,不需要上面的步驟              {              WriteInCurrentSlot( data, count ); //這裡同上,放入data二進制從右往左第一位開始共count位資料到記憶體,也就是m_pCurrentSlot裡面去。              m_FreeBitsInCurrentSlot -= count; //這裡同樣,放入了count個位,就要在m_FreeBitsInCurrentSlot裡面減去count個位,以便知道剩餘位是多少。              // if m_FreeBitsInCurrentSlot becomes 0 a nwe slot will initialized on the next request              }              }              }           

以上是整個的記憶體操作,截取bit位,執行個體化記憶體位址,結合if和else判斷,不得不佩服設計的精巧度。

繼續閱讀