撤消班次而不截断
Undoing shifts without truncating
本文关键字:撤消 更新时间:2023-10-16
我对此有点困惑。值不应该在移位后截断吗?
有谁知道为什么会这样?
long a, b, c, n;
//assign any value to a, set b and c to 0x000...0
n = 128; //any number works;
b = a << n;
c = b >> n;
a == (b >> n); // True
a == c; //True;
附言
我一直明白,如果向任何方向移动缓冲区,则"落"在缓冲区大小之外的值将被截断,并且除非您从原始缓冲区获取它们,否则它们基本上会丢失。对于我在汇编中使用过的每个平台来说都是如此,我认为这将扩展到更高级的语言。
但是,在 c++ 中,我可以将缓冲区(int 或 long(移位超过它可以容纳的位数,如果我随后向相反方向移动,则结果等于原始"缓冲区"。
用一个简化的例子来查看Godbolt:
long left_shift(unsigned long a) {
return (a << 128);
}
long right_shift(unsigned long a) {
return ((a << 128) >> 128);
}
我们得到的程序集看起来像这样(gcc-7.3.0,-O2
(:
left_shift(unsigned long):
xor eax, eax
ret
right_shift(unsigned long):
xor eax, eax
ret
正如HolyBlackCat所说,这是未定义的行为。 GCC 通过将移位的结果视为 0 来实现它,即使在我们可以逻辑推断结果的 right_shift
函数中也是如此。 Clang在left_shift
函数中什么都不做,这也是完美的cromulent。
看起来 C 编译器工作起来有点奇怪,但它绝对合理
如果移位数大于操作数长度(以位为单位(,则编译器将其除以操作数长度并使用提醒作为移位数
// A << N
L = length of A
if L < N
then N = A % L;
因此,您可以为班次数设置这样的数字,使其撤消禁用!!
N = 63 可能是您的答案,对于 A 上的任何值(甚至 A=1((A = 0 除外(,它不起作用(您的条件为 FALSE(
把 [61
尝试此代码以了解会发生什么
#include <cstdlib>
#include <cstdio>
using namespace std;
void DisplayBinary(unsigned int n, int l)
{
for (int i = l - 1 ; i >= 0; i--)
{
printf("%x", (n & (1 << i)) >> i);
}
}
int main(int argc, char** argv)
{
// x = 340
unsigned int x = 0x154;
for (int numberOfShifts = 0; numberOfShifts < 100; numberOfShifts++) {
printf("numberOfShifts = %dtresult = ", numberOfShifts);
DisplayBinary(x << numberOfShifts, 32);
printf("n");
}
return 0;
}
查看输出:
numberOfShifts = 0 result = 00000000000000000000000101010100
numberOfShifts = 1 result = 00000000000000000000001010101000
numberOfShifts = 2 result = 00000000000000000000010101010000
numberOfShifts = 3 result = 00000000000000000000101010100000
numberOfShifts = 4 result = 00000000000000000001010101000000
numberOfShifts = 5 result = 00000000000000000010101010000000
numberOfShifts = 6 result = 00000000000000000101010100000000
numberOfShifts = 7 result = 00000000000000001010101000000000
numberOfShifts = 8 result = 00000000000000010101010000000000
numberOfShifts = 9 result = 00000000000000101010100000000000
numberOfShifts = 10 result = 00000000000001010101000000000000
numberOfShifts = 11 result = 00000000000010101010000000000000
numberOfShifts = 12 result = 00000000000101010100000000000000
numberOfShifts = 13 result = 00000000001010101000000000000000
numberOfShifts = 14 result = 00000000010101010000000000000000
numberOfShifts = 15 result = 00000000101010100000000000000000
numberOfShifts = 16 result = 00000001010101000000000000000000
numberOfShifts = 17 result = 00000010101010000000000000000000
numberOfShifts = 18 result = 00000101010100000000000000000000
numberOfShifts = 19 result = 00001010101000000000000000000000
numberOfShifts = 20 result = 00010101010000000000000000000000
numberOfShifts = 21 result = 00101010100000000000000000000000
numberOfShifts = 22 result = 01010101000000000000000000000000
numberOfShifts = 23 result = 10101010000000000000000000000000
numberOfShifts = 24 result = 01010100000000000000000000000000
numberOfShifts = 25 result = 10101000000000000000000000000000
numberOfShifts = 26 result = 01010000000000000000000000000000
numberOfShifts = 27 result = 10100000000000000000000000000000
numberOfShifts = 28 result = 01000000000000000000000000000000
numberOfShifts = 29 result = 10000000000000000000000000000000
numberOfShifts = 30 result = 00000000000000000000000000000000
numberOfShifts = 31 result = 00000000000000000000000000000000
numberOfShifts = 32 result = 00000000000000000000000101010100 <<<===
numberOfShifts = 33 result = 00000000000000000000001010101000
numberOfShifts = 34 result = 00000000000000000000010101010000
numberOfShifts = 35 result = 00000000000000000000101010100000
numberOfShifts = 36 result = 00000000000000000001010101000000
numberOfShifts = 37 result = 00000000000000000010101010000000
numberOfShifts = 38 result = 00000000000000000101010100000000
numberOfShifts = 39 result = 00000000000000001010101000000000
numberOfShifts = 40 result = 00000000000000010101010000000000
numberOfShifts = 41 result = 00000000000000101010100000000000
numberOfShifts = 42 result = 00000000000001010101000000000000
numberOfShifts = 43 result = 00000000000010101010000000000000
numberOfShifts = 44 result = 00000000000101010100000000000000
numberOfShifts = 45 result = 00000000001010101000000000000000
numberOfShifts = 46 result = 00000000010101010000000000000000
numberOfShifts = 47 result = 00000000101010100000000000000000
numberOfShifts = 48 result = 00000001010101000000000000000000
numberOfShifts = 49 result = 00000010101010000000000000000000
numberOfShifts = 50 result = 00000101010100000000000000000000
numberOfShifts = 51 result = 00001010101000000000000000000000
numberOfShifts = 52 result = 00010101010000000000000000000000
numberOfShifts = 53 result = 00101010100000000000000000000000
numberOfShifts = 54 result = 01010101000000000000000000000000
numberOfShifts = 55 result = 10101010000000000000000000000000
numberOfShifts = 56 result = 01010100000000000000000000000000
numberOfShifts = 57 result = 10101000000000000000000000000000
numberOfShifts = 58 result = 01010000000000000000000000000000
numberOfShifts = 59 result = 10100000000000000000000000000000
numberOfShifts = 60 result = 01000000000000000000000000000000
numberOfShifts = 61 result = 10000000000000000000000000000000
numberOfShifts = 62 result = 00000000000000000000000000000000
numberOfShifts = 63 result = 00000000000000000000000000000000
numberOfShifts = 64 result = 00000000000000000000000101010100 <<<===
numberOfShifts = 65 result = 00000000000000000000001010101000
numberOfShifts = 66 result = 00000000000000000000010101010000
numberOfShifts = 67 result = 00000000000000000000101010100000
numberOfShifts = 68 result = 00000000000000000001010101000000
numberOfShifts = 69 result = 00000000000000000010101010000000
numberOfShifts = 70 result = 00000000000000000101010100000000
numberOfShifts = 71 result = 00000000000000001010101000000000
numberOfShifts = 72 result = 00000000000000010101010000000000
numberOfShifts = 73 result = 00000000000000101010100000000000
numberOfShifts = 74 result = 00000000000001010101000000000000
numberOfShifts = 75 result = 00000000000010101010000000000000
numberOfShifts = 76 result = 00000000000101010100000000000000
numberOfShifts = 77 result = 00000000001010101000000000000000
numberOfShifts = 78 result = 00000000010101010000000000000000
numberOfShifts = 79 result = 00000000101010100000000000000000
numberOfShifts = 80 result = 00000001010101000000000000000000
numberOfShifts = 81 result = 00000010101010000000000000000000
numberOfShifts = 82 result = 00000101010100000000000000000000
numberOfShifts = 83 result = 00001010101000000000000000000000
numberOfShifts = 84 result = 00010101010000000000000000000000
numberOfShifts = 85 result = 00101010100000000000000000000000
numberOfShifts = 86 result = 01010101000000000000000000000000
numberOfShifts = 87 result = 10101010000000000000000000000000
numberOfShifts = 88 result = 01010100000000000000000000000000
numberOfShifts = 89 result = 10101000000000000000000000000000
numberOfShifts = 90 result = 01010000000000000000000000000000
numberOfShifts = 91 result = 10100000000000000000000000000000
numberOfShifts = 92 result = 01000000000000000000000000000000
numberOfShifts = 93 result = 10000000000000000000000000000000
numberOfShifts = 94 result = 00000000000000000000000000000000
numberOfShifts = 95 result = 00000000000000000000000000000000
numberOfShifts = 96 result = 00000000000000000000000101010100 <<<===
numberOfShifts = 97 result = 00000000000000000000001010101000
numberOfShifts = 98 result = 00000000000000000000010101010000
numberOfShifts = 99 result = 00000000000000000000101010100000
相关文章:
- 在Qt中复制,剪切,粘贴,重命名,撤消和重做
- 如何撤消此代码上的 cin 重定向?
- 在Maya API中撤消操作
- Qt 撤消/重做和线程
- 撤消班次而不截断
- 在2048年游戏中撤消操作实施
- C 撤消命令 /反向以前的状态
- 与撤消历史的麻烦(Qundostack,Qundoview等)
- 在 QTextEdit 中撤消/重做
- C++向下转换以撤消功能覆盖
- 使用最小样板保存/加载+撤消/重做机制
- 撤消仪表convert依行动
- 使用 glm 撤消/防止围绕特定轴旋转
- 如何从 gdiplus 撤消拉绳
- 撤消后触发重做
- 如何撤消glTranslatef的效果
- 撤消按关键字隐藏的名称"using"。在孙子班不工作
- 撤消/重做的命令模式:何时不合并撤消命令
- 撤消/重做时释放内存时出现问题
- 可视化C++撤消和重做操作