假设 X 且 Y 是两个正整数, Y 是2的幂。然后这个表达式计算什么?
(X + Y-1)& 〜(Y-1)
我发现这个表达式出现在Memory Pool的某些c / c ++实现中( X 表示以字节为单位的对象大小, Y 表示以字节为单位的对齐,表达式返回块大小(以字节为单位)适合在内存池中使用。)
答案 0 :(得分:3)
&~(Y-1)
其中Y
是2的幂,将最后的 n 位归零,其中Y
= 2 n :Y-1
产生 n 1位,反转通过〜给出一个掩码,其末尾有 n 零,并且通过位-level &
将掩码为零的位清零。
有效地产生的数字是Y
2的幂的倍数。
最大限度地可以从数字中减去Y-1
,因此首先添加(X+Y-1) & ~(Y-1)
。这是一个不小于X
的数字,是Y
的倍数。
答案 1 :(得分:2)
它为您提供了当前地址Y
的下一个X
对齐地址。
说,您当前的地址X
为0x10000
,而您的路线为0x100
,它会为您提供0x10000
。但是,如果您当前的地址X
是0x10001
,那么您将获得" next"对齐的地址0x10100
。
这在您希望新对象始终与内存中的块对齐但不会使任何块未使用的情况下非常有用。所以你想知道下一个可用的块对齐地址是什么。
答案 2 :(得分:2)
让我们一点一点地分解它。
(X+Y-1) & ~(Y-1)
假设根据你的规则X = 11和Y = 16,整数是8位。
(11+16-1) & ~(16-1)
添加和减法
(26) & ~(15)
将其翻译成二进制文件
(0001 1010) & ~(0000 1111)
〜表示不反转或反转零和
(0001 1010) & (1111 0000)
&安培;意味着只取两个都是
的位0001 0000
转换回十进制
16
其他例子
X = 78, Y = 32 results in 96
X = 25, Y = 64 results in 64
X = 47, Y = 16 results in 48
所以,在我看来,这样做的目的是找到等于或大于X的Y的最低倍数。这可以用于查找内存块的开始/结束地址,或者它可用于在屏幕上定位项目,或任何其他可能的答案。但没有上下文,甚至可能是完整的代码示例。没有保证。
答案 3 :(得分:2)
为什么不尝试一些输入并观察会发生什么?
#include <iostream>
unsigned compute(unsigned x, unsigned y)
{
return (x + y - 1) & ~(y - 1);
}
int main()
{
std::cout << "(x + y - 1) & ~(y - 1)" << std::endl;
for (unsigned x = 0; x < 9; ++x)
{
std::cout << "x=" << x << ", y=2 -> " << compute(x, 2) << std::endl;
}
std::cout << "----" << std::endl;
std::cout << "(x + y - 1) & ~(y - 1)" << std::endl;
for (unsigned x = 0; x < 9; ++x)
{
std::cout << "(x=" << x << ", y=2) -> " << compute(x, 2) << std::endl;
}
return 0;
}
<强>输出:强>
第一组使用[0,8]中的x
,y
为常量2
。第二组使用[0,8]中的x
,y
为常量4
。
(x + y - 1) & ~(y - 1)
x=0, y=2 -> 0
x=1, y=2 -> 2
x=2, y=2 -> 2
x=3, y=2 -> 4
x=4, y=2 -> 4
x=5, y=2 -> 6
x=6, y=2 -> 6
x=7, y=2 -> 8
x=8, y=2 -> 8
----
(x + y - 1) & ~(y - 1)
(x=0, y=2) -> 0
(x=1, y=2) -> 2
(x=2, y=2) -> 2
(x=3, y=2) -> 4
(x=4, y=2) -> 4
(x=5, y=2) -> 6
(x=6, y=2) -> 6
(x=7, y=2) -> 8
(x=8, y=2) -> 8
很容易看到输出(即->
的结果右侧)始终是y
的倍数,使得输出大于或等于x
答案 4 :(得分:2)
首先我假设X和Y是无符号整数。
让我们来看看正确的部分:
让我们看看左侧:
结论,它是的最大倍数,大于或等于X 。
答案 5 :(得分:1)
它似乎提供了一个值的指定对齐,例如内存地址(例如,当你想获得下一个对齐的地址时)。
例如,如果您希望在段落边界处对齐内存地址,则可以编写
( address + 16 - 1 ) & ~( 16 - 1 )
或
( address + 15 ) & ~15
或
( address + 15 ) & ~0xf
在这种情况下,16之前的所有位都将归零。
这部分表达
( address + alignment - )
用于舍入。
和表达的这一部分
~( alignment - 1 )
用于构建一个掩码为低位的掩码。
答案 6 :(得分:1)
(X + Y-1)&amp; 〜(Y-1)
x = 7 = 0b0111
y = 4 = 0b0100
x+y-1 = 0b1010
y-1 = 3 = 0b0011
~(y-1) = 0b1100
(x+y-1) & ~(y-1) = 0b1000 = 8
-
x = 12 = 0b1100
y = 2 = 0b0010
x+y-1 = 13 = 0b1101
y-1 = 1 = 0b0001
~(y-1) = 0b1110
(x+y-1) & ~(y-1) = 0b1100 = 12
(x + y-1)&amp; 〜(y-1)是y的最大倍数,大于或等于x