|
目次
・整数の絶対値
・2整数のmax、min
・32ビットDIBの加算合成、パックドバイト飽和加算
整数の絶対値
inline int fastabs(int a)
{
int mask = a >> 31;
return (a ^ mask) - mask;
} |
これは有名ですね。一応、紹介しておきます。
2整数のmax, min
inline int fastmax(int a, int b)
{
int t = (a-b);
return a - (t & (t >> 31));
}
inline int fastmin(int a, int b)
{
int t = (a-b);
return b + (t & (t >> 31));
}
|
これも有名ですが、少しアレンジしてみました。
(a&~mask)|(b&mask) のタイプはよくあるのですが、このタイプはあまり無いみたいです。
どちらが速いかはわかりませんが、とりあえず演算子の数はこっちの方が少ないです。
32ビットDIBの加算合成、パックドバイト飽和加算
typedef unsigned int DWORD;
inline void packed_byte_add(DWORD *a, DWORD *b)
{
DWORD mask = (0x80808080 - ((((*a >> 1) & 0x7f7f7f7f) + ((*b >> 1) &
0x7f7f7f7f)
+ ((*a ^ *b) & 0x01010101)) >> 7 & 0x01010101)) ^ 0x80808080;
*a = (*a & (~mask)) + (*b | mask);
}
void kasan_gousei_32bpp(DWORD *a, DWORD *b)
{
DWORD mask = (0x80808080 - (((*a & 0xfefefefe) + (*b & 0xfefefefe)
+ ((*a & *b) & 0x02020202)) >> 8 & 0x01010101)) ^ 0x80808080;
*a = (*a & (~mask)) + (*b | mask);
} |
32ビット符号なし整数を、1バイト整数4個と見て、それぞれに飽和加算をします。
kasan_gouseiの方は32ビットDIBにて最上位1バイトが使用されていないのを利用し
少し最適化してあります。なので、最上位の計算結果は保障されません。
+ (*a & *b) & 0x02020202) を無くせば誤差は少々出ますが、多少高速になります。
MMX使えば一瞬です^^;
これは学校の友人と考え出したんですが、これも結構有名みたいですね。
|