alignSize函数解析
/** @brief Aligns a buffer size to the specified number of bytes.
The function returns the minimum number that is greater than or equal to sz and is divisible by n :
\f[\texttt{(sz + n-1) & -n}\f]
@param sz Buffer size to align.
@param n Alignment size that must be a power of two.
*/
static inline size_t alignSize(size_t sz, int n)
{
CV_DbgAssert((n & (n - 1)) == 0); // n is a power of 2
return (sz + n-1) & -n;
}
该函数的作用是计算最小的大于等于sz的且是n的倍数的值。
上述代码中要确保
n
n
n为
2
2
2的幂,这就保证了
n
n
n的二进制表达式中只有一个1,例如
n
=
2
(
二进制
00000010
)
,
n
=
4
(
二进制
00000100
)
,
n
=
8
(
二进制
00001000
)
n=2(二进制0000 0010),n=4(二进制0000 0100),n=8(二进制0000 1000)
n=2(二进制00000010),n=4(二进制00000100),n=8(二进制00001000)。
其中
CV_DbgAssert((n & (n - 1)) == 0);
为判断 n n n为 2 2 2的幂,上面讨论过,如果 n n n为 2 2 2的幂,则二进制表达式中只有一个 1 1 1,而 n − 1 n-1 n−1则是 1 1 1位取 0 0 0,后面全部变为 1 1 1(例如: 4 = 0100 , ( 4 − 1 ) = 0011 4=0100,(4-1)=0011 4=0100,(4−1)=0011),两者做&位运算结果为 0 0 0;
(sz + n-1) & -n;
上面这行代码中&左侧为
(
s
z
+
n
−
1
)
(sz+n-1)
(sz+n−1)而不是
(
s
z
+
n
)
(sz+n)
(sz+n)是为了确保最后的结果为最小的倍数,是为了排除
s
z
sz
sz正好是
n
n
n的倍数时,结果变成
s
z
+
n
sz+n
sz+n.
另外
−
n
-n
−n的二进制表达式为补码形式,首先将n的二进制全部取反,然后
+
1
+1
+1,结果为
1
1
1左侧的
0
0
0全部变为
1
1
1.
因此上面代码中两者按位&运算相当于将
s
z
+
n
−
1
sz+n-1
sz+n−1二进制中
n
n
n的倍数位的
1
1
1以外的
1
1
1全部变成
0
0
0,最后的结果就是小于
s
z
+
n
−
1
sz+n-1
sz+n−1并且最大的n的倍数。