Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 64位移位问题_C++_64 Bit - Fatal编程技术网

C++ 64位移位问题

C++ 64位移位问题,c++,64-bit,C++,64 Bit,为什么此代码不将0作为最后一个元素写入,而是将18446744073709551615写入? (用g++编译) #包括 使用名称空间std; int main(){ 无符号长x=(无符号长-1); 对于(int i=0;i好吧,你移动一次太多了。你从0移动到64(含64),总共移动了65次。你通常想要: for(int i=0; i < 64; i++) .... for(int i=0;i=类型的宽度” 这会导致未定义的行为: 我得到: test.c:8: warning: r

为什么此代码不将0作为最后一个元素写入,而是将18446744073709551615写入? (用g++编译)

#包括
使用名称空间std;
int main(){
无符号长x=(无符号长-1);

对于(int i=0;i好吧,你移动一次太多了。你从0移动到64(含64),总共移动了65次。你通常想要:

for(int i=0; i < 64; i++)
    ....
for(int i=0;i<64;i++)
....

将一个数字移动到等于或大于其宽度的位数是未定义的行为。您只能安全地将64位整数在0和63个位置之间移动。

当您将一个值移动的位数超过字长时,它通常会被移动
mod word size
。基本上,将其移动64位意味着按0位进行fting,这等于完全不移位。但您不应该依赖于此,因为标准中没有定义它,并且在不同的体系结构上可能会有所不同。

编译器发出的此警告应该是一个提示:

“警告:右移位计数>=类型的宽度”

这会导致未定义的行为:

我得到:

test.c:8: warning: right shift count >= width of type

因此,这可能是未定义的行为?

您的班次溢出。如果您注意到,GCC甚至警告您:

warning: right shift count >= width of type 警告:右移位计数>=类型的宽度 为什么?您将64作为一个有效的移位,这是一个未定义的行为。 从0到64,共有65个数字(包括0)。0是第一位(非常类似于数组)

#包括
使用名称空间std;
int main(){
无符号长x=(无符号长-1);
对于(int i=0;i<64;i++)

cout对于64位类型,-1的位模式看起来像十六进制的0xFFFFFFFFFFFFFF。因此,如果您将其作为无符号变量打印,您将看到无符号64位变量可以容纳的最大值,即18446744073709551615


当进行位移位时,我们不关心在这种情况下值的含义,也就是说,不管变量是有符号的还是无符号的,都以相同的方式处理(在这种情况下,将所有位向右移位一步).

另一个不小心的陷阱:我知道这是一个旧线程,但我来这里寻求帮助。我在64位计算机上被发现使用1<;<;k,而我的意思是1L<;<;k;在这种情况下没有编译器的帮助:(

您可以使用:

static inline pack_t lshift_fix64(pack_t shiftee, short_idx_t shifter){
  return (shiftee << shifter) & (-(shifter < 64));
}
static inline pack\t lshift\u fix64(pack\t shifte,short\u idx\t shifter){

return(shifte)这是错误的,右移的最大值是31,即移位量在内部总是被0x1F屏蔽。请参阅“英特尔手册”中的SHR指令。@jn:英特尔手册为“x86汇编”定义移位量C级未定义。@Mehrdad:正确-我刚刚检查了MSVC编译代码的程序集输出。如果移位量大于32,则用0x1F屏蔽,如果移位量大于64,则移位结果为零。右移位时,值是否有符号无关紧要。有符号的右移位填充高位st位到符号位,无符号右移将用0填充。实际上,用“k”位右移将产生与除以2^k相同的效果。我知道这是完全不相关的,但是,永远不要使用"使用namespace std;。这只是一个等待发生的意外,因为您或某个库恰好有一个与std中某个名称匹配的方法,所以花了数小时来跟踪发生的错误。>将其移位64意味着将其移位0位,这等于完全不移位:我以前见过这种说法,但我不明白这是怎么回事对于移位操作,这是正确的。从数学上讲,这对于移位操作来说是错误的。我描述了在x86体系结构上实际发生的情况,这些情况通常会导致观察到的行为(C未定义):CPU基本上忽略最左边的位,这相当于对移位位计数执行mod 64,然后等于零移位。我的意思不是说数学移位操作64位等于移位0.Ah。我假设数学和x86的结果为0x8000 0000(即趋向于全零)。但是自从
#include <iostream>

using namespace std;
int main(){
    unsigned long long x = (unsigned long long) (-1);
    for(int i=0; i < 64; i++)
        cout << i << " " << (x >> i) << endl;
    cout << (x >> 63) << endl;
    return 0;
}
static inline pack_t lshift_fix64(pack_t shiftee, short_idx_t shifter){
  return (shiftee << shifter) & (-(shifter < 64));
}
(-(shifter < 64)) == 0xffff ffff ffff ffff
(-(shifter < 64)) == 0x0