源碼
// Calculates (value * alpha256) / 255 in range [0,256],
// for [0,255] value and [0,256] alpha256.
pub fn alpha_mul_256(self,value: u32) -> Alpha256 {let prod = value * self.0;Alpha256((prod + (prod >> 8)) >> 8)
}
代碼分析
這個函數 alpha_mul_256 執行了一個快速的乘法運算,用于計算 (value * alpha256) / 255,其中 value 的范圍是 [0, 255],alpha256 的范圍是 [0, 256]。這個操作在圖形處理和顏色混合中很常見,比如計算帶透明度的顏色疊加。
參數:
-
self:一個 Alpha256 類型的值,表示透明度 alpha256,范圍是 [0, 256]。
-
value:一個 u32 類型的值,范圍是 [0, 255],表示要乘以透明度的值。
返回值:
- 返回 Alpha256 類型,表示 (value * alpha256) / 255 的結果,范圍是 [0, 256]。
計算過程:
- 計算乘積:
let prod = value * self.0;
- prod = value * alpha256,這是一個普通的乘法,范圍是 [0, 255 * 256]。
近似除以 255:
(prod + (prod >> 8)) >> 8
-
這里用了一個技巧來近似計算 prod / 255。
-
prod >> 8 等價于 prod / 256。
-
prod + (prod >> 8) 等價于 prod + prod / 256。
-
最后 >> 8 等價于除以 256,因此整體是 (prod + prod / 256) / 256。
為什么這是近似 prod / 255?
- 數學上,(prod + prod / 256) / 256 可以展開為:
(prod + prod / 256) / 256 = prod / 256 + prod / (256 * 256)
= prod * (1/256 + 1/65536)
= prod * (257/65536)
= prod * (257/65536)
-
而 1 / 255 ≈ 257 / 65536,因為 257 / 65536 ≈ 0.00392156862745098,而 1 / 255 ≈ 0.00392156862745098,兩者非常接近。
-
因此,這個技巧用整數運算高效地近似了除以 255 的操作。
- 返回結果:
- 最終結果是一個 Alpha256 類型,范圍是 [0, 256]。
示例:
假設 value = 255(最大值),alpha256 = 128(半透明):
-
prod = 255 * 128 = 32640。
-
prod >> 8 = 32640 / 256 = 127。
-
prod + (prod >> 8) = 32640 + 127 = 32767。
-
(prod + (prod >> 8)) >> 8 = 32767 / 256 = 127。
- 精確計算:255 * 128 / 255 = 128,這里結果是 127,誤差為 1,在合理范圍內。
總結:
這個函數用高效的整數運算(乘法和位移)近似計算了 (value * alpha256) / 255,避免了昂貴的除法操作,適合性能敏感的圖形計算場景。雖然結果可能有微小誤差,但在大多數情況下可以接受。