标签: bit-shift

何时按位运算是合适的

我知道什么是按位操作的基本前提(虽然会欣赏"for dummies"的解释); 但是我不知道何时使用这种技术是合适的.

我的理解是,较旧的CPU架构可以比其他操作更快地执行按位操作,因此知道如何使用它们是有利的.鉴于此情况已不再适用; 是否仍然适合执行它们,如果是,它的目的和条件是什么?(我对C#语境特别感兴趣,但很高兴收到一般答案)

c# algorithm bit-manipulation bit-shift

11
推荐指数
2
解决办法
2344
查看次数

将int值按位移位的目的是什么?

看一下java.nio.DirectByteBuffer类的源代码,我发现了这个:

if ((length << 0) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) ....
Run Code Online (Sandbox Code Playgroud)

将长度移位零比特的目的是什么?可能这是一些性能优化还是其他什么?

java bit-shift

11
推荐指数
2
解决办法
2347
查看次数

C ++ 20是否为“溢出”的有符号整数很好地定义了左移?

在当前的C ++标准草案中,左移位运算符的定义如下[expr.shift]

的值E1 << E2唯一的值一致来E1×2^E22^N,其中N是结果的类型的宽度。

考虑int E1 = 2^31-1 = 2'147'483'647E2 = 1并且int具有32位。再有就是数的无限数量一致,以 E1×2^E2 = 4'294'967'2942^N = 2^32,即,所有的数字4'294'967'294 + k×2^32,其中k的任意整数。示例是4'294'967'294k=0)或-2k=-1)。

我不明白这些数字中的唯一值表示标准的含义。这是否意味着可以由结果数据类型表示的唯一值?然后,我假设结果定义为-2。这种解释正确吗?

在C ++ 20之前,定义是不同的,这种情况将导致未定义的行为。我想这个变化与负号整数的强制性2's补码表示有关。

实际上,现在不再E1需要非负数。因此,似乎将-1 << 1其定义为-2。那也对吗?

c++ bit-shift language-lawyer c++20

11
推荐指数
1
解决办法
501
查看次数

左移 unsigned int 是否大于其位域宽度,但小于其未定义的类型大小?

struct Type {
    uint8_t var : 3;
};

int main()
{
    struct Type bar;
    bar.var = 1;
    uint8_t baz = bar.var << 5;
}
Run Code Online (Sandbox Code Playgroud)

根据标准,左移超过左操作数类型的宽度是未定义的行为:

6.5.7 按位移位运算符/3对每个操作数执行整数提升。结果的类型是提升后的左操作数的类型。如果右操作数的值为负数或大于或等于提升的左操作数的宽度,则行为未定义。

但是位域呢?这里不是至少八位吗?

c bit-shift undefined-behavior integer-promotion bit-fields

11
推荐指数
1
解决办法
1314
查看次数

为什么这个按位右移似乎不起作用?

有人可以向我解释为什么面具根本没有向右移动吗?您可以使用任何代替1的结果,结果将是相同的.

unsigned mask = ~0 >> 1;
printf("%u\n", mask);
Run Code Online (Sandbox Code Playgroud)

c bit-manipulation binary-operators bit-shift not-operator

10
推荐指数
2
解决办法
2485
查看次数

C++中的Shift运算符

如果移位运算符之后的值大于左侧操作数中的位数,则结果是未定义的.如果左侧操作数是无符号的,则右移是逻辑移位,因此高位将用零填充.如果左侧操作数已签名,则右移可能是也可能不是逻辑移位(即,行为未定义).

有人可以解释一下上面这些行是什么意思吗?

c++ operators bit-shift

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

在C#中获取整数的上下字节并将其作为char数组发送到com端口,如何?

CI会这样做

int number = 3510;

char upper = number >> 8;

char lower = number && 8;

SendByte(上部);

SendByte(低级);

上下都是= 54

在C#我这样做:

            int number = Convert.ToInt16("3510");
            byte upper = byte(number >> 8);
            byte lower = byte(number & 8);
            char upperc = Convert.ToChar(upper);
            char lowerc = Convert.ToChar(lower);
            data = "GETDM" + upperc + lowerc;
            comport.Write(data);
Run Code Online (Sandbox Code Playgroud)

但是在调试器编号= 3510,upper = 13和lower = 0这没有任何意义,如果我将代码更改为>> 6 upper = 54这绝对是奇怪的.

基本上我只想从16位数字中获取上下字节,并在"GETDM"之后将其发送到com端口

我怎样才能做到这一点?它在C语言中非常简单,但在C#中我完全被难倒了.

c# bytearray bitmask bit-shift char

10
推荐指数
2
解决办法
4万
查看次数

按位运算和转换

我很难理解这段代码的工作方式和原因.我在这个任务中的合作伙伴完成了这一部分,我无法得到他,以了解它的工作原理和原因.我已经尝试了一些不同的东西来理解它,但任何帮助将非常感激.此代码使用2的补码和32位表示.

/* 
 * fitsBits - return 1 if x can be represented as an 
 *  n-bit, two's complement integer.
 *   1 <= n <= 32
 *   Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 15
 *   Rating: 2
 */
int fitsBits(int x, int n) {
    int r, c;
    c = 33 + ~n;
    r = !(((x << c)>>c)^x);
    return r;
}
Run Code Online (Sandbox Code Playgroud)

c bit-manipulation bit-shift bitwise-operators twos-complement

10
推荐指数
2
解决办法
1万
查看次数

c/c ++ left shift unsigned vs signed

我有这个代码.

#include <iostream>

int main()
{
    unsigned long int i = 1U << 31;
    std::cout << i << std::endl;
    unsigned long int uwantsum = 1 << 31;
    std::cout << uwantsum << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

打印出来.

2147483648
18446744071562067968
Run Code Online (Sandbox Code Playgroud)

在Arch Linux 64位,gcc,常春藤桥架构上.

第一个结果是有道理的,但我不明白第二个数字的来源.1表示为4byte int signed或unsigned is

00000000000000000000000000000001
Run Code Online (Sandbox Code Playgroud)

当你向左移动31次时,你最终得到了

10000000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)

没有?我知道向左移动正数基本上是2 ^ k,其中k是你移动它的次数,假设它仍然适合于界限.为什么我得到这么奇怪的数字?

c++ bit-shift

10
推荐指数
2
解决办法
1万
查看次数

隐式转换:以下警告是否有效?

这个问题C++运算符(和其他几个)中的隐式类型转换规则

如果其中一个是long long unsigned int,则另一个被提升为long long unsigned int

但是,如果我在MSVC下执行以下操作:

unsigned int a = <some expression>;
unsigned long long b = a << 32ULL;
Run Code Online (Sandbox Code Playgroud)

第二行生成以下警告:

warning C4293: '<<': shift count negative or too big, undefined behavior
Run Code Online (Sandbox Code Playgroud)

32ULL是一个64位无符号值,因此根据隐式转换规则,这应该意味着a转换unsigned long long为.因此,我将64位值移位32位,显然是一个定义明确的操作.

MSVC是否有漏洞或者我的逻辑存在缺陷?

c++ bit-shift unsigned-long-long-int integer-promotion language-lawyer

10
推荐指数
1
解决办法
251
查看次数