嘿,我是自学的关于按位,我在互联网上看到算术移位(>>)的数字是一半.我想测试一下:
44 >> 1 returns 22, ok
22 >> 1 returns 11, ok
11 >> 1 returns 5, and not 5.5, why?
Run Code Online (Sandbox Code Playgroud)
另一个例子:
255 >> 1 returns 127
127 >> 1 returns 63 and not 63.5, why?
Run Code Online (Sandbox Code Playgroud)
谢谢.
我是位操作技巧的新手,我写了一个简单的代码来查看在单个数字上进行单个位移的输出. 2
#include <iostream>
int main(int argc, char *argv[])
{
int num=2;
do
{
std::cout<<num<<std::endl;
num=num<<1;//Left shift by 1 bit.
} while (num!=0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出如下.
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536
131072
262144
524288
1048576
2097152
4194304
8388608
16777216
33554432
67108864
134217728
268435456
536870912
1073741824
-2147483648
Run Code Online (Sandbox Code Playgroud)
显然,连续比特移位到左边由1个比特,将导致零,因为它已经在上面进行,但为什么计算机输出一个负数在最后终止在循环之前(自NUM接通零)??
然而,当我替换时int num=2,unsigned int num=2我获得相同的输出,除了最后一个数字是这个时间显示为正,2147483648而不是-2147483648
我gcc在Ubuntu Linux上使用编译器
我记得在集会课上,我们学习了m68k处理器,你可以做3种转换.线性移位,循环移位和带有延伸的圆形移位.
最后一个,带有extend的循环移位,基本上是向左或向右旋转所有位,但它将最外面的位置放到一个延伸位,然后再将它移动到开头(如果你再次移动1).
我画了一张小图:
基本上,在循环移位中使用第33位,但当然不会出现在32位字中.第33位是处理器的X标志,代表扩展.你可以很容易地使用任何状态标志,例如进位标志,但我想摩托罗拉人想要保留那个标志,这样它就不会被覆盖,以防万一你需要进行正常职责的进位标志.一些算法也需要用extend进行旋转.
无论如何,使用extend旋转的目的是什么?它是干什么用的?需要什么?看起来很奇怪.为什么世界上你需要第33位?
我读过这个和这个,两个相关的问题,但他们并没有谈及该循环移位与延伸.
我知道正常班次的一些用途.基本上除以2,或测试可分性,并置换随机性位.类似的东西.但是我想不出为什么你需要在旋转中插入一些扩展位而不会在结果中出现.
编辑:我对它的任何使用感兴趣,无论是现代的还是旧的,如果它在m68k上都无关紧要.m68k只是我遇到它的第一个位置(我从来没有在那里使用它).
我希望alwaysPositive被分配一个正数,其中包含lareValue1和largeValue2的所有可能值(这些值至少为1).
以下语句导致缓冲区溢出:
int alwaysPositive = (largeValue1 + largeValue2) / 2;
Run Code Online (Sandbox Code Playgroud)
我知道我可以通过减去和添加来阻止它:
int alwaysPositive = largeValue1 + ((largeValue2 - largeValue1) / 2);
Run Code Online (Sandbox Code Playgroud)
但在其他编程语言中,我可以使用无符号位移来实现这一诀窍:
int alwaysPositive3 = (largeValue1 + largeValue2) >>> 1;
Run Code Online (Sandbox Code Playgroud)
我怎么能在C#中做到这一点?
以下答案都解决了这个问题.可能有很多方法可以做到这一点,但它们(包括我的解决方案)都有一个共同点:它们看起来都是混淆的.
宣言...
const
n = 2 shl 33
Run Code Online (Sandbox Code Playgroud)
n在没有编译器投诉的情况下将常数设置为值4!
也...
Caption := IntToStr(2 shl 33);
Run Code Online (Sandbox Code Playgroud)
...返回4而不是8589934592.看起来编译器计算如下:
2 shl 33 = 2 shl(33和$ 1F)= 4
但没有任何警告或溢出.
如果我们声明:
const
n: int64 = 2 shl 33;
Run Code Online (Sandbox Code Playgroud)
常数中的数字仍然是4而不是8589934592.
任何合理的工作?
我有一个二进制文件,将作为字符读入.其他人将每个角色移位到左侧未知次数(假设有包裹).我希望能够读入每个角色,然后将换档换到右侧(换档的次数我想必须手动计算出来,因为我还没想出另一种方法).
所以,我目前的想法是我读了一个字符,用temp创建一个副本然后使用XOR:
char letter; //will hold the read in letter
char temp; //will hold a copy of the letter
while(file.read(&letter, sizeof(letter)) //letter now holds 00001101
{
temp = letter; //temp now holds 00001101
letter >>= 1; //shift 1 position to the right, letter now holds 00000110
temp <<= 7; //shift to the left by (8-1), which is 7, temp now holds 10000000
letter ^= temp; //use XOR to get the wrap, letter now holds 10000110
cout << letter;
}
Run Code Online (Sandbox Code Playgroud)
这在我筋疲力尽的头脑中是有道理的,但它不起作用......我无法弄清楚为什么.char的大小是1个字节,所以我想我只需要乱用8位. …
<<当移位位的值大于数据类型的总位数时,移位运算符如何工作?
例如,
int i = 2;
int j = i<<34;
System.out.println(j);
Run Code Online (Sandbox Code Playgroud)
整数的大小是32位,但是我们正在移位34位.这是如何运作的?
假设我们-5用四位表示一个十进制数:1011,并想将一个数左移乘以2:
1011 << 1
Run Code Online (Sandbox Code Playgroud)
此操作返回0110,它是6,而不是我们希望的-10。
(我假设这仅适用于第二位为0的负数,即负数接近某个范围的最小可表示负数)
binary bit-manipulation bit-shift negative-number twos-complement
根据我之前关于如何比较组合位是否包含特定位的问题,我遇到了这个错误.
int flag1 = 1 << 0;
int flag4 = 1 << 5;
int combined = flag1 | flag4;
if (combined & flag1 == flag1) // <-- Operator & cannot be applied to int, boolean
Run Code Online (Sandbox Code Playgroud)
如果我将标志转换为字节,则错误替换int为byte.
我有一个来自文本文件的整数输入,我需要将其转换为二进制并进行左移位12位.
所以,如果我的数字是6.二进制是110.我的最终输出应该是1100亿,位移了12位.
我试过了:
i = 6
h = int(bin(i)[2:])<<12
Run Code Online (Sandbox Code Playgroud)
但是,这会产生错误的输出.问题是bin(i)返回一个字符串,所以我不得不将它转换为int但是然后使用shift运算符移动整数而不是二进制.