留意 LLRB 和典型 rbtree 的落差,見關於紅黑樹
l_offt 在 linux 中的定義是什麼 type?
在 fibdrv.c 使用到l_offt
作為參數型態,可能發生什麼潛在的問題
src
: linux v6.2.8
l_offt
:
defined in
include/linux/types.h
L46
__kernel_loff_t
:
defined in
include/uapi/asm-generic/posix_types.h
L88
long long 的 range 為
-9223372036854775808
~ 9223372036854775807
,loff_t 單位為 byte , TiB
kernel module 計算完 big num 之後是怎麼把資料傳到 user space 的 ?
用 __copy_to_user
這個 kernel API 。
那這個 API 最後面參數的 size 範圍有多大。
最後一個參數的型別為 unsigned long ,在 LP64 的機器上是 64bit 的寬度。
對,linux 在處理這個議題的時候是尊重使用者電腦的架構決定寬度,若在 32 位元的機器上 unsigned long 的寬度則會是 32 位元。
針對正整數在相鄰敘述進行 mod 10 和 div 10 操作,如何減少運算成本?
根據除法原理:
可以將 mod 10 和 div 10 合併,以此來減少除法的數量。
這裡參考了 Hacker's Delight 來實作除法。
這裡採用 bitwise operation 來實作除法,因為 有包含 這個因數,無法完全用 的次方項來表示,因此結果會是不準確的。然而,觀察上面的程式碼後可以發現, temp
不可能會大於 19
,因此只需要考慮 19
~0
的情況即可。
我們的目標是,得到 temp / 10
且直到小數點後第一位都是精準的。
這時,我們可以提出一個猜想,假設我們我們目標的最大數是 n
, l
則是比 n
還要小的非負整數。那麼假設 ( 是十位數 b 是個位數),且 ( 是十位數, 是個位數),則只要以 算出來的除數在 除以該除數後在經確度內,則 除與該除數仍然會在經確度內。證明如下:
假設 是除數,
因此,當初我的猜想也成立,接下來只需要針對 19
來做討論即可。
接下來只需要找到這之中可以用除法來表示的除數即可。
方法如下,透過 bitwise operation 得到的算式必定是 其中 為非負整數, 正整數。因此只需要透過查看 再配對適合的 即可。
其中, 便是一個可以使用的解。
接著,嘗試透過 bitwise operation 來配對數字。
關於這段程式碼,我的思路如下:
temp
減去 div 10 的結果乘與
其中 (((q << 2) + q) << 1)
就是 ( 也就是 測試結果如下:
結果正確。
可包裝為以下函式:
使用案例:
延伸閱讀: