contributed by < yan112388 >
程式碼解釋
計算非負整數 N 的平方根
log2(N) 含式來計算 N 的以 2 為底的對數,並將結果轉換為整數,儲存在 msb 中,藉此得到 N 的最高非零位的位置while 迴圈,將數字 N 右移(相當於將數字除以 2),直到剩下最高的非零位元,得到該位置a = 1 << msb,這等同於設置 a 為 2 的 msb 次方,此值將作為初始步長result 被初始化為 0,將用來儲存最終的平方根while 迴圈,只要 a 不為 0,迴圈就會繼續。在每次的迭代中:(result + a) * (result + a) 是否小於或等於 N,相當於檢查 (result + a) 的平方是否小於或等於 Na 被加到 result 上,因為 (result + a) 仍然是 N 的平方根的下界a 都會被右移一位,相當於將 a 除以 2,藉此將搜尋的步長做調整a 變為 0 時,迴圈結束,此時 result 包含了 N 的平方根的整數部分result版本三:
以 Digit-by-digit calculation 方式,數學式的原理與細節尚未搞懂,待釐清。
目的:計算 in 除以 10 的商和餘數,並將結果儲存在 div 和 mod 中
程式碼如下:
欲計算 in 除以 10,10 可以表達為 1.25 * 8,所以我們可以先計算 0.75 * in,接著除以 8,就可以得到in 除以 10 的近似值
(in | 1) 亦即 in + 1,作用為將 in 的最低位元設為 1。
(in | 1) = in(in | 1) = in + 1可以將此操作看成是一種數值的修正,計算 0.75 * in 時,實際上是在計算 3 * in / 4。當 in 是奇數時,此算數為精確的。但是當 in 是偶數時,由於我們進行了除法並向下取整數,結果會比實際的 0.75 * in 略小,加 1 可以補償這個誤差。
q = (q >> 8) + x 都相當於將 q 除以 256,256 可以表達為 2 的 8 次方。在此有 4 行,表示將 x 除以 2 的 32 次方。q 右移 3 個位元,即提取 q 的高位元作為商。((q & ~0x7) + (*div << 1)) 亦同於 div * 8 + *div * 2計算以 2 為底的對數
版本二:
使用了二分搜法的想法
i 右移 16 位,代表著將其範圍縮小到原來的 1/65536重複此過程,檢查輸入是否大於等於 256()、16 () 及 。每次檢查成功,就將結果加上相應的值(),並將 i 右移相應的位數。
版本三
__builtin_clz,其功能為找到 x 最高位數前面有幾個 0 , x 為 0 時,未定義。31 - __builtin_clz(v) 就等於 v 的最高非零位的位置,也就是 floor(log2(v))。__builtin_clz(0) 是未定義的這種問題,使用了 v | 1 而非 v。 v | 1 的作用是將 v 的最低位設為 1,確保了進入 __builtin_clz is never的輸入永遠非0。EWMA 數學式展開如下:
avg->internalval流程:
val 值乘以 ,作為初始的 EWMA 值 (val << avg->factor)internal 值乘以 再減去 internal ,得到 ,對應於公式中的val << avg.factor 將新的樣本值 val 左移 avg->factor 位,相當於將其乘以 進行縮放,對應於公式中的 avg->weight 位,相當於除以 Q:為甚麼 會對應於公式中的 ?
欲求 ,將之展開,得到:
程式碼中:
最後,將 除以 :