在C语言中,移位操作符(<<,>>)是算术还是逻辑的?

13 浏览
0 Comments

在C语言中,移位操作符(<<,>>)是算术还是逻辑的?

在C语言中,移位运算符(<<和>>)是算术运算符还是逻辑运算符?

0
0 Comments

在C语言中,位移运算符(<<,>>)是算术的还是逻辑的?这个问题出现的原因是因为在C语言中,位移运算符的行为在不同的情况下有不同的定义。具体来说,对于右移位操作符,对于无符号类型的操作数,结果是将操作数除以2的n次方取整;对于有符号类型的非负值操作数,结果也是将操作数除以2的n次方取整。而对于有符号类型的负值操作数,其结果是未定义的。对于左移位操作符,对于无符号类型的操作数,结果是将操作数乘以2的n次方再取模;对于有符号类型的非负值操作数,结果是将操作数乘以2的n次方;而对于有符号类型的负值操作数,结果是未定义的。

为了解决这个问题,可以通过对操作数和结果的类型进行推导和限制。根据C99标准,每个操作数必须是整数类型,并且对每个操作数进行整数提升。结果的类型是左操作数提升后的类型。如果右操作数的值为负数或大于等于左操作数提升后类型的位宽,那么行为是未定义的。

对于左移位操作符,结果的值是左操作数左移右操作数位的结果,空出的位用零填充。如果左操作数具有无符号类型,则结果的值是左操作数乘以2的n次方,再对结果类型能表示的最大值加1取模。如果左操作数具有有符号类型且为非负值,并且左操作数乘以2的n次方能在结果类型中表示,那么结果就是左操作数乘以2的n次方。否则,行为是未定义的。

对于右移位操作符,结果的值是左操作数右移右操作数位的结果。如果左操作数具有无符号类型或者左操作数具有有符号类型且为非负值,结果的值是左操作数除以2的n次方的整数部分。如果左操作数具有有符号类型且为负值,结果的值是实现定义的。

,C语言中的位移操作符都是算术的,但在一些情况下行为是未定义的或者实现定义的。这个问题的出现是因为C语言标准在定义位移操作符的行为时,更多地以数学的方式进行定义,而不是将操作数视为位的流动。这也是为什么标准在某些情况下将行为定义为未定义或实现定义的原因。

0
0 Comments

C语言中的移位运算符(<<, >>)是算术的还是逻辑的?

根据《C程序设计语言》第二版的说法,对于有符号值的右移操作,结果是依赖于具体的实现的。

维基百科上说,C/C++通常对有符号值进行算术右移。

基本上,你需要测试你的编译器,或者不依赖于它。我在VS2008帮助文档中找到的关于当前MS C++编译器的信息是,他们的编译器会进行算术右移。

根据这个回答,行为不仅取决于编译器,还取决于编译器和(处理器)架构的组合。

编译器的选择在某些情况下可能会受到处理器架构的影响,但是大多数现代编译器会将带符号值的右移操作视为算术右移,即使需要添加符号扩展代码。

总结起来,移位运算符(<<, >>)在C语言中的行为是依赖于具体的实现的,编译器和处理器架构的组合会影响其行为。如果需要确定移位操作的行为,需要进行测试或者不依赖于特定的实现。

0
0 Comments

在C语言中,<<和>>是位移操作符。当进行左移操作时,算术位移和逻辑位移没有区别。当进行右移操作时,位移类型取决于被位移的值的类型。

当对无符号值进行位移操作时,C语言中的>>操作符是逻辑位移。当对有符号值进行位移操作时,>>操作符是算术位移。

例如,假设是32位机器:

signed int x1 = 5;

assert((x1 >> 1) == 2);

signed int x2 = -5;

assert((x2 >> 1) == -3);

unsigned int x3 = (unsigned int)-5;

assert((x3 >> 1) == 0x7FFFFFFD);

因此,当右移有符号值时,需要小心处理。

实际上,对于正数的有符号左移操作也会导致未定义行为,如果结果的数学值(不受位数限制)无法表示为该有符号类型的正数值。总之,在对有符号值进行右移操作时,必须小心处理。

关于<<操作符,如果结果的算术值能够表示为正数值,但是其行为被认为是未定义的。唯一的原因我能想到的是为了允许使用补码和反码机器上的LSL指令,而不是用相同的操作符。即使如此,也应该是“实现指定”的,这样可以允许这些假想的补码和反码机器有自己奇怪的行为。

在使用unsigned类型时,可以通过将有符号值强制转换为unsigned类型来避免问题。

此外,之前在某些平台上,对于<<操作符是算术位移还是逻辑位移存在分歧,甚至是在使用二进制补码平台上也存在分歧。标准的作者希望避免强制要求那些可能需要改变现有代码的实现,因此将<<操作符的行为留给了实现。

总之,在处理位移操作时,需要小心处理并遵循C语言的规范。在特定的实现中,可能会发生未定义行为或实现定义行为。

0