当我移位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) 我<<在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问题吗?我没有在规格中找到的行为?我根本不懂的正常行为? …
我对整个位移和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++考试.实践考试中的一个问题是:
这个陈述的结果是什么?
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代码:
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也能工作?后一种形式不是更容易理解吗?在这种情况下有没有理由使用位移?是否有任何边缘情况,两者不一样?
根据我之前关于如何比较组合位是否包含特定位的问题,我遇到了这个错误.
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)
如果我将标志转换为字节,则错误替换int为byte.
让我们考虑一个函数(它的可能实现之一),它将无符号短值(或任何其他无符号整数类型)的右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位的替代实现可能是受欢迎和有趣的,但这个问题的主要焦点是发布的代码的有效性.
请考虑以下代码:
#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) 在将此标记为重复之前,请阅读以下内容,并检查我的代码*我的更新代码!
所以我的问题是,我必须实现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) 我试图在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