标签: bit-shift

sra(右移算术)与 srl(逻辑右移)

请看一下这两段伪汇编代码:

1)

li $t0,53

sll $t1,$t0,2
srl $t2,$t0,2
sra $t3,$t0,2

print $t1  
print $t2  
print $t3  
Run Code Online (Sandbox Code Playgroud)

2)

li $t0,-53


sll $t1,$t0,2
srl $t2,$t0,2
sra $t3,$t0,2

print $t1
print $t2
print $t3
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,输出为:
212
13
13

后者是:
-212
107374...
-14
但不应该:sra (-53) = - (srl 53) ?

assembly mips bit-shift twos-complement

5
推荐指数
1
解决办法
4万
查看次数

将按位移位运算符应用于有符号类型:UB 和 Impl。定义

C++03 标准告诉我们,将按位移位运算符应用于有符号类型的结果可以是 UB 和 Impl。定义为负值。我的问题如下:为什么对于操作符<<它有未定义的行为,而对于操作符>>它只是实现定义的?是否有严格的原因导致结果<<也不能被实现定义?
提前致谢。

c++ bit-shift

5
推荐指数
1
解决办法
618
查看次数

无法理解C代码中的移位操作符行为

看看这个示例C代码(以一个测试用例为例):

main() {
  unsigned long a, b;
  int c;
  c = 32;
  a = 0xffffffff << 32;
  b = 0xffffffff << c;
  printf ("a=%x, b=%x\n", a, b);
}
Run Code Online (Sandbox Code Playgroud)

打印: a=0, b=ffffffff

我不明白为什么b不是零,就像一个.我在Microsoft C和GCC上测试了这个.

更新:我修复了愚蠢的错字(当然应该是<< c而不是<< b).但我的问题仍然存在,例如结果仍然相同.

c bit-shift

5
推荐指数
2
解决办法
1225
查看次数

从`std :: vector <char>`里面的位获取整数

我有一个vector<char>,我希望能够从向量中的一系列位获得无符号整数.例如

比特值的可视化

我似乎无法编写正确的操作来获得所需的输出.我想要的算法是这样的:

  • & 第一个字节用 (0xff >> unused bits in byte on the left)
  • << 结果留下了输出字节数*一个字节的位数
  • | 这与最终输出
  • 对于每个后续字节:
    • << 由每个字节的(字节宽度 - 索引)*位左边
    • | 这个字节带有最终输出
  • | 最终输出的最后一个字节(未移位)
  • >> 最终输出由右边字节中未使用的位数

这是我尝试编码它,但没有给出正确的结果:

#include <vector>
#include <iostream>
#include <cstdint>
#include <bitset>

template<class byte_type = char>
class BitValues {
    private:
    std::vector<byte_type> bytes;
    public:
        static const auto bits_per_byte = 8;
        BitValues(std::vector<byte_type> bytes) : bytes(bytes) {
        }
        template<class return_type>
        return_type get_bits(int start, int end) {
            auto byte_start = (start - (start % bits_per_byte)) / bits_per_byte; …
Run Code Online (Sandbox Code Playgroud)

c++ bit-manipulation bytearray bit-shift bit

5
推荐指数
1
解决办法
1039
查看次数

5
推荐指数
2
解决办法
3711
查看次数

算术右移位有哪些实际用例?

我偶然发现了一个问题,询问是否曾经不得不在实际项目中使用位移.我在许多项目中都使用了相当广泛的位移,但是,我从来不必使用算术位移,即位移​​,其中左操作数可能是负的,符号位应该移位而不是零.例如,在Java中,您将使用运算>>符进行算术位移(同时>>>执行逻辑移位).在经过深思熟虑之后,我得出的结论是,我从未使用>>过可能为负的左操作数.

正如本回答中所述,算术移位甚至是在C++中定义的实现,因此与Java相比 - 在C++中甚至没有用于执行算术移位的标准化运算符.答案还说明了一个有趣的问题,我甚至都没有意识到负面数字的变化:

+63 >> 1 = +31 (integral part of quotient E1/2E2)
00111111 >> 1 = 00011111
-63 >> 1 = -32 
11000001 >> 1 = 11100000
Run Code Online (Sandbox Code Playgroud)

因此,当看到这些位时,-63>>1收益率-32是显而易见的,但也许不是大多数程序员一见钟情的预期.更令人惊讶的是(但在查看位时再次显而易见)-1>>1-1,不是0.

那么,可能负值算术右移的具体用例是什么?

c c++ java bit-manipulation bit-shift

5
推荐指数
2
解决办法
1088
查看次数

C++中64位整数的Bitwise(Bitshift)操作

我正在尝试处理位板,这需要我在64位无符号整数中设置一个特定的位.要设置位i,我对所讨论的位板执行按位OR运算,左移数字.

#include <stdint.h>
uint64_t kings = 0ULL; // Also tried unsigned long long int before.
kings |= 1 << i;
Run Code Online (Sandbox Code Playgroud)

它从第0位到第31位工作正常,但不能用于第32位到第63位.我怀疑这是因为右侧的评估恰好是32位整数.因此,我尝试了一个临时变量.

uint64_t temp = 0ULL;
temp |= 1 << i;
Run Code Online (Sandbox Code Playgroud)

也许它仍然将右侧评估为32位整数,或者它是我无法弄清楚的其他问题.要输出整数,我使用的是std :: bitset <64>.例如:

uint64_t kings = 0ULL;
kings |= 1 << 3;
kings |= 1 << 59;
Run Code Online (Sandbox Code Playgroud)

预期小数值:576460752303423496

实际:8

std::bitset<64> x(kings);
std::cout << x;
Run Code Online (Sandbox Code Playgroud)

位值:0000000000000000000000000000000000000000000000000000000000001000

显然,只有国王| = 1 << 3; 工作正常.

总之,第32到63位有什么问题,我该如何解决?

c++ bit-manipulation bit-shift bitwise-or bitboard

5
推荐指数
2
解决办法
8333
查看次数

如何获取负数的最后16位二进制数字并将它们连接起来?

我正在研究一些按位运算符,我想提取数字的最后16位二进制数字并对它们进行操作.我基本上想要看到像0xFFFFFFFF这样的负数,然后提取LSB FFFF并将它们连接起来,0这样我最终得到一个零,所以它看起来像0x0000FFFF.我只关心较小的负数,所以LSB应该是我需要的所有信息.

这是我在C中的方法:

#include <stdio.h>

int main(){
    int a = -1, c = 0;
    short b = (short)a;
    printf("a is %x\nb is %x",a,b);
    c = (0 << 16) | b;
    printf("\nc is %x\n", c); 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的思维过程是,我可以在我转换int a到一个较短,使得它看起来像FFFF,而不是FFFFFFFF我将有一个更好的时间.对我来说不幸的是,这只是打印出ffffffff变量

c int bit-manipulation bit-shift bitwise-operators

5
推荐指数
1
解决办法
89
查看次数

带符号 int 的位移位重置过多

请看下面的代码片段,它基本上只是将 1 个字节向左移动 24 位。

uint64_t i = 0xFFFFFFFF00000000;
printf("before: %016llX \n", i);
i += 0xFF << 24;
printf("after : %016llX \n", i);

// gives:
// before: FFFFFFFF00000000
// after : FFFFFFFEFF000000
Run Code Online (Sandbox Code Playgroud)

最重要的 32 位是FFFFFFFEE在最后观看)。这并不像我预期的那样。我不明白为什么左移 1 个字节 24 位会触及位 #32(位 #31 应该是最后一个修改的)它把最后一个F( 1111) 变成了E( 1110) 。

为了使其正常工作,我使用了0xFF无符号 ( 0xFFU)。

uint64_t i = 0xFFFFFFFF00000000;
printf("before: %016llX \n", i);
i += 0xFFU << 24;
printf("after : %016llX \n", i); …
Run Code Online (Sandbox Code Playgroud)

c unsigned bit-shift

5
推荐指数
1
解决办法
62
查看次数

标准中哪里说当你进行按位运算时,它的行为会像大尾数法?

无论字节序如何,位移和其他操作的行为总是像大字节序一样。所以小的数字在右边,大的数字在左边。符号位也位于左侧。

我的问题是哪里明确说是这样的?我的C11草案副本甚至没有提到字节顺序,并且在按位部分有一些我不理解的数学表达式,所以我不确定这部分在哪里。

c bit-manipulation bit-shift

5
推荐指数
2
解决办法
170
查看次数