這是提高精度的像素混合操作的一部分。
typedef unsigned uint;
uint h(uint x) {
x &= 0xff;
return x << 8 | x;
}
uint g(uint x, uint y) {
return h(x) * h(y) >> 24;
}
我查看了編譯器輸出,發現了一個非常有趣的行。
g:
movzx edi, dil
movzx esi, sil
imul esi, edi
imul eax, esi, 66049 # <---
shr eax, 24
ret
這可以反編譯為,
uint g_(uint x, uint y) {
return (x & 0xff) * (y & 0xff) * 66049 >> 24;
}
我無法理解乘以如何66049產生所需的結果。它背后的數學原理是什么?
uj5u.com熱心網友回復:
66049 是 0x10201 十六進制。這是一個重要的線索,因為:
(x << 8 | x) = (x * 0x101)
(假設 0 ≤ x ≤ 0xFF),則(x << 8 | x) * (y << 8 | y)與 相同x * y * 0x101 * 0x101。
0x101 * 0x101可以簡化為-這0x10201是你的魔法常數。
那么為什么是x * 0x101一樣的(x << 8 | x)呢?通過十進制示例應該很容易看出這一點。如果您將 0-99 的任何數字乘以 101,它會復制數字 - 例如,32 * 101 = 3232。這是因為乘以 100 實際上只是在末尾添加 0(即 32 * 100 = 3200)和額外的 1只需添加原始值(32 * 101 = 32 * 100 32 * 1 = 3200 32 = 3232)。相同的原則適用于十六進制(或二進制)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/489737.html
