标签: bit-shift

需要帮助理解K&R C第2章中的"getbits()"方法

在第2章,关于按位运算符的部分(第2.9节),我无法理解其中一个示例方法是如何工作的.

这是提供的方法:

unsigned int getbits(unsigned int x, int p, int n) {
    return (x >> (p + 1 - n)) & ~(~0 << n);
}
Run Code Online (Sandbox Code Playgroud)

这个想法是,对于给定的数字x,它将返回从位置p开始的n位,从右边开始计数(最右边的位是位置0).给出以下方法:main()

int main(void) {
    int x = 0xF994, p = 4, n = 3;
    int z = getbits(x, p, n);
    printf("getbits(%u (%x), %d, %d) = %u (%X)\n", x, x, p, n, z, z);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

getbits(63892 (f994), 4, 3) = 5 (5)

我得到了部分内容,但我对"大局"感到困扰,主要是因为我不理解的比特(没有双关语).

我特别遇到问题的部分是补充部分:~(~0 << …

c bit-manipulation operators bit-shift complement

28
推荐指数
3
解决办法
9399
查看次数

我应该在Java中按位移2除以?

可能重复:
比Java中的乘法和除法更快地移位位?.净?
快速Java优化问题

很多年前,在大学里,我学会了正确地按位移动实现与除以2相同的操作,但通常要快得多.自从9-10年前我了解到这一点以来,我不确定Java在这方面是如何出现的.Java编译器是否自动将二分频转换为位移操作,还是应该自己在代码中手动执行位移操作?

java performance bit-manipulation bit-shift division

28
推荐指数
4
解决办法
3万
查看次数

右移C中的负数

我有C代码,我在其中执行以下操作.

int nPosVal = +0xFFFF;   // + Added for ease of understanding
int nNegVal = -0xFFFF;   // - Added for valid reason
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试

printf ("%d %d", nPosVal >> 1, nNegVal >> 1);
Run Code Online (Sandbox Code Playgroud)

我明白了

32767 -32768
Run Code Online (Sandbox Code Playgroud)

这是预期的吗?

我能够想到类似的东西

65535 >> 1 = (int) 32767.5 = 32767
-65535 >> 1 = (int) -32767.5 = -32768
Run Code Online (Sandbox Code Playgroud)

也就是说,-32767.5四舍五入为-32768.

这种理解是否正确?

c bit-shift negative-number

26
推荐指数
3
解决办法
4万
查看次数

SHL和SAL之间的差异在80x86

我已经学会了如何使用80x86汇编程序,所以在逐位移位操作中,我遇到了SAL和SHL使用的问题.我的意思是代码行之间的区别如下:

MOV X, 0AAH
SAL X, 4

MOV X, 0AAH
SHL X, 4
Run Code Online (Sandbox Code Playgroud)

什么时候应该使用SHL和使用SAL?它们有什么区别?

assembly bit-shift x86-16

26
推荐指数
3
解决办法
4万
查看次数

算术按位右移"a shr b",带有存储在变量中的有符号整数 - 结果错误!内部Delphi的错误?

我有一个关于Delphi中位移行为的问题(或者更可能是错误报告)(在Borland Delphi 7中测试过).

目标:使用任意数字向右执行"算术"按位移位.

这意味着必须扩展符号位 - 如果设置了一个数字的最高有效位,则将从左侧填充二进制数,而不是0.

因此,算术右移后的数字"-1"必须保持相同的数字(所有位= 1),但是"逻辑移位"(总是用零填充数字)必须给出最大正整数(最大正有符号整数) ,为了正确)

我只在32位系统上测试过它(Windows); 而且,我需要它以32位整数显式工作.

当源编号存储在变量中时,看起来Delphi中存在带有"shr"的内部错误.

我的示例代码:

program bug;

{$APPTYPE CONSOLE}

var
I:Integer;
C:Cardinal;

begin
I := -1;  // we’ll need that later
C := $FFFFFFFF;
Run Code Online (Sandbox Code Playgroud)

(这只是开始).接下来,让我们尝试一些"shr":

Writeln('0) ', -1 shr 1 );
Writeln('1) ', $FFFFFFFF shr 1 );
Run Code Online (Sandbox Code Playgroud)

"-1"是等效于"$ FFFFFFFF"的签名.似乎"shr"行为(算术或逻辑)基于源号是签名还是不签名(整数或基数)的事实.

输出是:

0) -1
1) 2147483647
Run Code Online (Sandbox Code Playgroud)

非常正确.然后我需要尝试手动将这些数字转换为整数或基数:

Writeln('2) ', Integer(-1) shr 1 );
Writeln('3) ', Integer($FFFFFFFF) shr 1 );
Writeln('4) ', Cardinal(-1) shr 1 );
Writeln('5) ', Cardinal($FFFFFFFF) shr 1 ); …
Run Code Online (Sandbox Code Playgroud)

delphi integer bit-shift delphi-7 unsigned-integer

26
推荐指数
1
解决办法
1886
查看次数

当sizeof(int)== 4时,1 << 31在C中定义得很好

根据这个问题的答案:

E1 << E2的结果是E1左移E2位位置; 腾出的位用零填充.如果E1具有无符号类型,则结果的值为E1×2 E2,比结果类型中可表示的最大值减少一个模数.如果E1具有带符号类型和非负值,并且E1×2 E2可在结果类型中表示,那么这就是结果值; 否则,行为未定.

这似乎意味着1 << 31未定义.

但是,如果我使用,GCC不会发出警告1 << 31.它确实发出一个问题1 << 32. 链接

那是哪个呢?我误解了标准吗?海湾合作委员会有自己的解释吗?

c bit-shift undefined-behavior language-lawyer

25
推荐指数
3
解决办法
1924
查看次数

Java:对负数进行右移

关于负数的右移操作我很困惑,这里是代码.

int n = -15;
System.out.println(Integer.toBinaryString(n));
int mask = n >> 31;
System.out.println(Integer.toBinaryString(mask));
Run Code Online (Sandbox Code Playgroud)

结果是:

11111111111111111111111111110001
11111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)

为什么要将负数移31而不是1(符号位)?

java bit-manipulation bit-shift bitwise-operators negative-number

24
推荐指数
2
解决办法
3万
查看次数

如何在C中评估换档操作符?

当我使用shift进行操作时,我最近发现了一种(奇怪的)行为>> <<!

为了解释它,让我编写这个小的可运行代码,执行两个应该相同的操作(在我的理解中),但我对不同的结果感到惊讶!

#include <stdio.h>

int main(void) {
    unsigned char a=0x05, b=0x05;

    // first operation
    a = ((a<<7)>>7);

    // second operation
    b <<= 7;
    b >>= 7;

    printf("a=%X b=%X\n", a, b);
    return 0;
} 
Run Code Online (Sandbox Code Playgroud)

跑步时,a = 5b = 1.我希望它们都等于1!有人可以解释为什么我得到这样的结果?

PS:在我的环境中,大小unsigned char为1个字节

c bit-shift integer-promotion

24
推荐指数
3
解决办法
1918
查看次数

无符号右移的行为应用于字节变量

考虑以下Java代码片段

byte b=(byte) 0xf1;
byte c=(byte)(b>>4);
byte d=(byte) (b>>>4);
Run Code Online (Sandbox Code Playgroud)

输出:

c=0xff
d=0xff
Run Code Online (Sandbox Code Playgroud)

预期产量:

c=0x0f
Run Code Online (Sandbox Code Playgroud)

怎么样?为b二进制1111 0001 无符号右移之后0000 1111,因此0x0f,但为什么是0xff 怎么了?

java bit-shift

23
推荐指数
2
解决办法
9706
查看次数

移位运算符的结果类型是什么?

考虑以下清单:

#include <type_traits>
#include <cstdint>

static_assert(std::is_same_v<decltype(31), int32_t>);
static_assert(std::is_same_v<decltype(31u), uint32_t>);

static_assert(std::is_same_v<decltype((signed char)1 << 1), int32_t>);
static_assert(std::is_same_v<decltype((signed char)1 << 1u), int32_t>);
static_assert(std::is_same_v<decltype((unsigned char)1 << 1), int32_t>);
// Signed result for unsigned char
static_assert(std::is_same_v<decltype((unsigned char)1 << 1u), int32_t>);
// But unsigned for uint32_t
static_assert(std::is_same_v<decltype(1u << 1u), uint32_t>);
Run Code Online (Sandbox Code Playgroud)

它可以与 GCC 和 Clang 很好地编译。我很困惑operator<<(uint8_t, uint32_t)。为什么要签署结果?

c++ types bit-shift integer-promotion

22
推荐指数
2
解决办法
2117
查看次数