为什么这个移位操作加上按位只能工作到 31?
Why this shift operation plus bitwise works only up to 31?
为什么下面的移位运算有效并最终相等?
这种模式有什么名字吗?
我想知道写这段代码的人脑子里到底在想什么!
int i = 0x1;
i |= 0x1 << 1;
i |= 0x1 << 2;
i |= 0x1 << 3;
i |= 0x1 << 4;
i |= 0x1 << 5;
int j = 5;
if( ((0x1 << (j + 1)) - 1) == i)
{
// WHY?
}
我试图检查这是否适用于所有数字,但只适用于 31。
for (int i = 1; i <= 100; i++) {
int total_1 = 0x1;
for (int j = 1; j <= i; j++) {
total_1 |= 0x1 << j;
}
int total_2 = (0x1 << (i + 1)) - 1;
if (total_2 == total_1) {
} else {
cout << i << endl;
break;
}
}
更新
请解释第一部分为什么它们最终会相等?
UPDATE Please explain the first part why they would end up equal?
((0x1 << (j + 1)) - 1)
将 j
低位设置为 1
示例:
若j
为3,j+1
为4,1
平移4为0b1000
;减去 1 - 你得到 0b0111
回复:Is there any name for this pattern?
- 我看过 here,这个模式用过几次,但没有命名。可能太明显了:)
Is there any name for this pattern?
0x1u << pos
(或 1u << pos
)是一种获取数字的模式,仅设置位置 pos
中的位。使用带符号的 0x1
通常是 anti-pattern.
i |= 1u << pos
是一种模式,用于在整数 i
.
的位置 pos
设置一个位
(1u << pos) - 1
是一种模式,用于创建仅在小于 pos
.
的位置设置位的模式
Why shift operation below works and end up equal?
也许查看中间结果可能会有所帮助:
// least significant byte
int i = 0x1; // 0b0000'0001
i |= 0x1 << 1; // 0b0000'0011
i |= 0x1 << 2; // 0b0000'0111
i |= 0x1 << 3; // 0b0000'1111
i |= 0x1 << 4; // 0b0001'1111
i |= 0x1 << 5; // 0b0011'1111
int j = 5;
0x1 << (j + 1)
0x1 << 6 // 0b0100'0000
(0x1 << (j + 1)) - 1
0b0100'0000 - 1 // 0b0011'1111
only works up to 31
int
在您的系统上可能是 32 位宽。如果将 32 位 0x1 左移 31 位或更多位,则程序的行为是未定义的。如果你要使用0x1u
,那么你可以移动31,但32及以上将是UB。
为什么下面的移位运算有效并最终相等? 这种模式有什么名字吗? 我想知道写这段代码的人脑子里到底在想什么!
int i = 0x1;
i |= 0x1 << 1;
i |= 0x1 << 2;
i |= 0x1 << 3;
i |= 0x1 << 4;
i |= 0x1 << 5;
int j = 5;
if( ((0x1 << (j + 1)) - 1) == i)
{
// WHY?
}
我试图检查这是否适用于所有数字,但只适用于 31。
for (int i = 1; i <= 100; i++) {
int total_1 = 0x1;
for (int j = 1; j <= i; j++) {
total_1 |= 0x1 << j;
}
int total_2 = (0x1 << (i + 1)) - 1;
if (total_2 == total_1) {
} else {
cout << i << endl;
break;
}
}
更新
请解释第一部分为什么它们最终会相等?
UPDATE Please explain the first part why they would end up equal?
((0x1 << (j + 1)) - 1)
将 j
低位设置为 1
示例:
若j
为3,j+1
为4,1
平移4为0b1000
;减去 1 - 你得到 0b0111
回复:Is there any name for this pattern?
- 我看过 here,这个模式用过几次,但没有命名。可能太明显了:)
Is there any name for this pattern?
0x1u << pos
(或 1u << pos
)是一种获取数字的模式,仅设置位置 pos
中的位。使用带符号的 0x1
通常是 anti-pattern.
i |= 1u << pos
是一种模式,用于在整数 i
.
pos
设置一个位
(1u << pos) - 1
是一种模式,用于创建仅在小于 pos
.
Why shift operation below works and end up equal?
也许查看中间结果可能会有所帮助:
// least significant byte
int i = 0x1; // 0b0000'0001
i |= 0x1 << 1; // 0b0000'0011
i |= 0x1 << 2; // 0b0000'0111
i |= 0x1 << 3; // 0b0000'1111
i |= 0x1 << 4; // 0b0001'1111
i |= 0x1 << 5; // 0b0011'1111
int j = 5;
0x1 << (j + 1)
0x1 << 6 // 0b0100'0000
(0x1 << (j + 1)) - 1
0b0100'0000 - 1 // 0b0011'1111
only works up to 31
int
在您的系统上可能是 32 位宽。如果将 32 位 0x1 左移 31 位或更多位,则程序的行为是未定义的。如果你要使用0x1u
,那么你可以移动31,但32及以上将是UB。