标签: bit-shift

位移操作不会返回预期结果

当我移位1 << 63时,为什么Java返回-2147483648

预期的结果是9 223 372 036 854 775 808使用Wolfram Alpha和我的计算器进行测试.

我测试过:

System.out.print((long)(1 << (63)));
Run Code Online (Sandbox Code Playgroud)

java bit-manipulation bit-shift

6
推荐指数
2
解决办法
7370
查看次数

操作无效:float64类型的移位

<<在Golang中使用shift运算符面临一个奇怪的问题.在我的最终代码中,移位值将是两个整数的绝对值.但是,Go包只定义了值的Abs函数float64,所以我需要转换参数来使用它,然后将结果转换回来uint.

最后,这个值将被用作float64参数,因此我将其转换回来float64.

问题是返回值的转换似乎不像我预期的那样工作......

var test float64

// all the following lines are working as expected
test = float64(1 << 10)
test = float64(1 << uint(10))
test = float64(1 << uint(float64(11-1)))
test = float64(1 << uint(-float64(1-11)))

// but this one does not: error at compilation
test = float64(1 << uint(math.Abs(10)))
Run Code Online (Sandbox Code Playgroud)

我收到的错误是:

invalid operation: 1 << uint(math.Abs(10)) (shift of type float64)
Run Code Online (Sandbox Code Playgroud)

但是,似乎只有施法操作才有效:

var test = uint(math.Abs(10))
fmt.Println(reflect.Kind(test))
// uint32
Run Code Online (Sandbox Code Playgroud)

这是一个Golang问题吗?我没有在规格中找到的行为?我根本不懂的正常行为? …

bit-shift go

6
推荐指数
1
解决办法
1302
查看次数

如何获得第n位值

我对整个位移和c ++都很陌生.

假设我有一个uint8_t 00100100(36),我想检查第3位是否已设置.以下是我现在只做一点的代码.

uint8_t x = 36;
    if(x&1<<3)
        printf("is set");
Run Code Online (Sandbox Code Playgroud)

如何检查第3 位第6位是否已设置?我想检查几个比特组合,如第5或第7或第8.

什么是最优雅的方式呢?

c++ bits bit-shift

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

为什么将此位evalue移位到51

我正在学习C++考试.实践考试中的一个问题是:

这个陈述的结果是什么?

cout <<(11>>1)<<1<<endl;
Run Code Online (Sandbox Code Playgroud)

照我看来.11保持二进制当量

1011.
Run Code Online (Sandbox Code Playgroud)

将此二进制数向右移1位使其成为:

0101
Run Code Online (Sandbox Code Playgroud)

然后将第一个向左移动就可以了

1010 
Run Code Online (Sandbox Code Playgroud)

评估为10.

但是,通过在我的编译器中运行相同的语句,它会将数字评估为51.有人可以向我解释这个吗?

c++ bit-shift bitwise-operators

6
推荐指数
2
解决办法
188
查看次数

为什么先左移位然后右移,而不是AND-ing?

我遇到了这段C代码:

typedef int gint
// ...
gint a, b;
// ...
a = (b << 16) >> 16;
Run Code Online (Sandbox Code Playgroud)

为了便于记法,我们假设b = 0x11223344在这一点上.据我所知,它做了以下事情:

  • b << 16 会给 0x33440000
  • >> 16 会给 0x00003344

因此,丢弃了16个最高位.

为什么有人会写,(b << 16) >> 16如果b & 0x0000ffff也能工作?后一种形式不是更容易理解吗?在这种情况下有没有理由使用位移?是否有任何边缘情况,两者不一样?

c bit-manipulation bit-shift

6
推荐指数
1
解决办法
164
查看次数

运算符"&"不能应用于byte,int,boolean

根据我之前关于如何比较组合位是否包含特定位的问题,我遇到了这个错误.

    int flag1 = 1 << 0;
    int flag4 = 1 << 5;

    int combined = flag1 | flag4;

    if (combined & flag1 == flag1) // <-- Operator & cannot be applied to int, boolean
Run Code Online (Sandbox Code Playgroud)

如果我将标志转换为字节,则错误替换intbyte.

java bit-shift bit

6
推荐指数
1
解决办法
3598
查看次数

左移位和丢弃位

让我们考虑一个函数(它的可能实现之一),它将无符号短值(或任何其他无符号整数类型)的右N位置零.可能的实现可能如下所示:

template<unsigned int shift>
unsigned short zero_right(unsigned short arg) {
  using type = unsigned short;

  constexpr type mask = ~(type(0));
  constexpr type right_zeros = mask << shift; // <-- error here
  return arg & right_zeros;
}

int check() {
  return zero_right<4>(16);
}
Run Code Online (Sandbox Code Playgroud)

使用此代码,我可以访问的所有编译器以某种方式抱怨可能的溢出.CLang是最明确的一个,有以下明确的信息:

错误:从'int'到'const type'的隐式转换(又名'const unsigned short')将值从1048560更改为65520 [-Werror,-Wconstant-conversion]

这个代码看起来很清晰,对我来说很明显,但是当3个编译器抱怨时,我变得非常紧张.我在这里错过了什么吗?真的有可能发生腥病吗?

PS虽然zeriong out左边X位的替代实现可能是受欢迎和有趣的,但这个问题的主要焦点是发布的代码的有效性.

c++ integer-overflow bit-shift language-lawyer

6
推荐指数
1
解决办法
538
查看次数

使g ++使用SHLD/SHRD指令

请考虑以下代码:

#include <limits>
#include <cstdint>

using T = uint32_t; // or uint64_t

T shift(T x, T y, T n)
{
    return (x >> n) | (y << (std::numeric_limits<T>::digits - n));
}
Run Code Online (Sandbox Code Playgroud)

根据godbolt,clang 3.8.1 为-O1,-O2,-O3生成以下汇编代码:

shift(unsigned int, unsigned int, unsigned int):
        movb    %dl, %cl
        shrdl   %cl, %esi, %edi
        movl    %edi, %eax
        retq
Run Code Online (Sandbox Code Playgroud)

而gcc 6.2(即使有-mtune=haswell)生成:

shift(unsigned int, unsigned int, unsigned int):
    movl    $32, %ecx
    subl    %edx, %ecx
    sall    %cl, %esi
    movl    %edx, %ecx
    shrl    %cl, %edi …
Run Code Online (Sandbox Code Playgroud)

c++ optimization assembly gcc bit-shift

6
推荐指数
1
解决办法
546
查看次数

PHP中的无符号右移/零填充右移/ >>>(Java/JavaScript等效)

在将此标记为重复之前,请阅读以下内容,并检查我的代码*我的更新代码!

所以我的问题是,我必须实现Java/JavaScript'>>>'(无符号右移/零填充右移),但我无法以完全相同的方式工作.

我已经选择了我在SO和Web上找到的11个最有希望的实现(链接在代码中添加为注释)并添加了一些测试用例.不幸的是功能返回的Java/JS相同响应所有的测试.(也许其中一些只在32位系统上工作)

实时代码+ JS + PHP结果演示(点击运行):
http://phpfiddle.org/main/code/bcv7-bs2q*
http://phpfiddle.org/main/code/dpkw-rxfe

最接近的功能是:

// http://stackoverflow.com/a/27263298
function shr9($a,$b) { 
    if($a>=0) return $a>>$b;
    if($b==0) return (($a>>1)&0x7fffffff)*2+(($a>>$b)&1);
    return ((~$a)>>$b)^(0x7fffffff>>($b-1)); 
}
Run Code Online (Sandbox Code Playgroud)

// http://stackoverflow.com/a/25467712
function shr11($a, $b) { 
    if ($b > 32 || $b < -32) {
        $m = (int)($b/32);
        $b = $b-($m*32);
    }

    if ($b < 0)
        $b = 32 + $b;

    if ($a < 0) 
    { 
        $a = ($a >> 1); 
        $a &= 2147483647; 
        $a …
Run Code Online (Sandbox Code Playgroud)

javascript php java bit-manipulation bit-shift

6
推荐指数
1
解决办法
940
查看次数

C中的类型转换和按位操作的结果取决于顺序

我试图在int, char, short, long不使用头文件的情况下打印最小值<limit.h>.所以按位操作将是一个不错的选择.但有些奇怪的事发生了

该声明

printf("The minimum of short: %d\n", ~(((unsigned short)~0) >> 1));
Run Code Online (Sandbox Code Playgroud)

给我

The minimum of short: -32768
Run Code Online (Sandbox Code Playgroud)

但声明

printf("The minimum of short: %d\n", ~((~(unsigned short)0) >> 1));
Run Code Online (Sandbox Code Playgroud)

给我

The minimum of short: 0
Run Code Online (Sandbox Code Playgroud)

这种现象也发生在char.但它不会发生在long, int.为什么会这样?

值得一提的是我使用VS Code作为我的编辑器.当我unsigned char在语句中移动光标时

printf("The minimum of char: %d\n", (short)~((~(unsigned char)0) >> 1));
Run Code Online (Sandbox Code Playgroud)

它给了我一个提示,(int) 0而不是(unsigned char)0我所期望的.为什么会这样?

c bit-shift bitwise-operators implicit-conversion visual-studio-code

6
推荐指数
1
解决办法
402
查看次数