按位运算符和“字节序”

85

在位运算中,endianness对逻辑或移位操作有影响吗?

我正在做有关位运算符的作业,但我无法理解它,我认为我已经陷入了endianness。也就是说,我正在使用小端机器(像大多数机器一样),但这是否需要考虑还是一个浪费的事实?

如果有影响的话,我正在使用C语言。


1
重复:https://dev59.com/J2w05IYBdhLWcg3wiyRJ - 0andriy
4
在我看来,这两个问题略有不同。第一个问题类似于“在任何CPU上,128 << 2 == 512是否成立?”,而第二个问题则是指“在任何CPU上,128 << 2的布局是否为0x02 0x00?” - kolen
5个回答

86

字节序只影响数据在内存中的存储方式。一旦处理器加载数据进行操作,字节序就完全无关紧要了。无论字节序如何,移位、位运算等操作都会按照预期执行(数据逻辑上以低位到高位的方式排列)。


25
从逻辑上讲,它不应该是“高位到低位”,对吗? - legends2k
1
@legends2k:有同样的想法 - Giorgi Moniava
1
@legends2k:是的。左移 = 乘以2的幂。右移 = 除以2的幂(对于负值,舍入方式与整数除法不同)。 - Peter Cordes
2
@JoshC:不,PDP-10只是按照逻辑上数据定义的方式执行操作,而不管其存储器/寄存器中的哪个位被安排在哪里。例如:当你加两个32位整数时,你无需担心处理器必须转换数据才能使加法工作(你也无需担心硬件字节中位的顺序) - ALU只是做“正确的事情”,因为它的连线方式与硬件配合得很好。位移也是同样的道理 - 它们以一种抽象出硬件字节/位顺序细节的方式对数据进行操作。 - mtraceur
1
@JoshC:(续)在C语言中,位移操作符的定义方式更加抽象:它们是根据它们产生的值来定义的,而不是根据它们如何移动底层位。因此,如果你在某个晦涩的平台上,硬件位移指令会产生无效的位布局,例如你将一个值位移到填充位,那么符合规范的编译器需要产生可以解决这个问题的指令,据我所知。 - mtraceur
显示剩余3条评论

71
位运算符抽象了字节序。例如,>> 运算符总是将位向最低有效数字位移动。但这并不意味着在使用它们时可以完全忽略字节序,例如,在处理较大结构中的单个字节时,不能总是假定它们会落在相同的位置。
short temp = 0x1234;
temp = temp >> 8;

// on little endian, c will be 0x12, on big endian, it will be 0x0
char c=((char*)&temp)[0];

澄清一下,我并不完全反对其他答案。我试图强调的是,尽管位运算符本质上是中性的,但在编写代码时不能忽略字节顺序的影响,特别是与其他运算符结合使用时。


1
你基本上不同意每个人的观点,但是你的答案却被投票选为最佳。如何识别这种行为? - Frank V
我已经添加了进一步的澄清。 - 1800 INFORMATION
2
那么进一步澄清,您的意思是,除非我实际检索字节值,否则一切都没问题? - Suvarna Pattayil
1
O.o 所以 >> 和 << 根本不是右移和左移;它们是“向最低有效位移动和向最高有效位移动”。这使得“通过移位进行除法和乘法”与字节序无关...现在我困惑了,如果通过 memcpy 进行强制类型转换会不会搞砸这个。 - Dmytro

6

正如其他人提到的那样,移位是由C语言规范定义的,并且与字节序无关,但右移的实现可能因架构使用补码算术还是反码算术而有所不同。


4

这取决于情况。如果不将数字转换为新类型,则可以透明地处理字节序。

但是,如果您的操作涉及一些新类型转换,则需要谨慎使用。

例如,如果您想要右移一些位并显式或隐式地转换为新类型,则字节序很重要!

要测试字节序,您可以将一个int转换为char

int i = 1;

char *ptr;

...

ptr = (char *) &i;  //Cast it here

return  (*ptr);

...或者创建一个联合体... {union { int i = 1; char a[4];} b;return b.a[3] == 1;} //大端 - user3139831

3

您没有指定语言,但通常,像C这样的编程语言在位操作中会抽象地处理字节序。因此,在位操作中,字节序并不重要。


2
考虑到这个问题没有修订,我很惊讶你说他没有提到语言,但他确实提到了,并且标记为C。 - Simeon Pilgrim
2
@Simeon:在我回答这个问题的时候还没有。在短时间内由单个作者进行的编辑将被合并为一个版本。这就是为什么你看到它只有一个修订版本的原因。 - Mehrdad Afshari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接