简体   繁体   English

为什么是0x7FFFFFFFull | (1 << 31)在C ++中返回0xFFFFFFFFFFFFFFFF?

[英]Why is 0x7FFFFFFFull | (1 << 31) returning 0xFFFFFFFFFFFFFFFF in C++?

When I do (0x7fffffff | 0x8000000) I am getting 0xffffffffffffffff instead of the expected 0xffffffff. 当我这样做(0x7fffffff | 0x8000000)时,我得到0xffffffffffffffff而不是预期的0xffffffff。 What am I missing? 我错过了什么?

Some sample code and output to illustrate my question. 一些示例代码和输出来说明我的问题。

Code: 码:

#include <iostream>

using namespace std;

int main()
{
        unsigned long long val = 0;

        for (int i = 0; i < 64; i++) {
                val |= 0x1 << i;
                cout << i << ": " << std::hex << val << std::dec << endl;
        }

        return 0;
}

Output: 输出:

0: 1
1: 3
2: 7
3: f
4: 1f
5: 3f
6: 7f
7: ff
8: 1ff
9: 3ff
10: 7ff
11: fff
12: 1fff
13: 3fff
14: 7fff
15: ffff
16: 1ffff
17: 3ffff
18: 7ffff
19: fffff
20: 1fffff
21: 3fffff
22: 7fffff
23: ffffff
24: 1ffffff
25: 3ffffff
26: 7ffffff
27: fffffff
28: 1fffffff
29: 3fffffff
30: 7fffffff
31: ffffffffffffffff
32: ffffffffffffffff
33: ffffffffffffffff
34: ffffffffffffffff
35: ffffffffffffffff
36: ffffffffffffffff
37: ffffffffffffffff
38: ffffffffffffffff
39: ffffffffffffffff
40: ffffffffffffffff
41: ffffffffffffffff
42: ffffffffffffffff
43: ffffffffffffffff
44: ffffffffffffffff
45: ffffffffffffffff
46: ffffffffffffffff
47: ffffffffffffffff
48: ffffffffffffffff
49: ffffffffffffffff
50: ffffffffffffffff
51: ffffffffffffffff
52: ffffffffffffffff
53: ffffffffffffffff
54: ffffffffffffffff
55: ffffffffffffffff
56: ffffffffffffffff
57: ffffffffffffffff
58: ffffffffffffffff
59: ffffffffffffffff
60: ffffffffffffffff
61: ffffffffffffffff
62: ffffffffffffffff
63: ffffffffffffffff

Firstly your code does not do what you say in your title/question; 首先,你的代码没有按你在标题/问题中所做的那样做; I have edited the title. 我已经编辑了标题。

The problem is 1 << 31 . 问题是1 << 31 If you have 32-bit int (which apparently you do, judging by the results), this cause arithmetic overflow. 如果你有32位int (显然你这样做,根据结果判断),这会导致算术溢出。 In C++14 this is implementation-defined behaviour; 在C ++ 14中,这是实现定义的行为; prior to C++14 it causes undefined behaviour. 在C ++ 14之前,它会导致未定义的行为。 Reference . 参考

Usually the implementation-defined behaviour will be to generate the int with the sign bit set and the other bits unset. 通常,实现定义的行为是生成符号位设置的int,其他位未设置。 In 2's complement this value is INT_MIN . 在2的补码中,该值为INT_MIN You then perform arithmetic between an unsigned long long and an int . 然后,您在unsigned long longint之间执行算术运算。 This is defined as: the int is converted to unsigned long long . 这被定义为: int被转换为unsigned long long

Converting signed integers to unsigned is done by wrapping it around (modular arithmetic) modulo ULLONG_MAX+1 . 将有符号整数转换为无符号是通过将其包围(模运算)模ULLONG_MAX+1 So the result of (unsigned long long)INT_MIN is a very large positive number, in fact 0xFFFFFFFF80000000 . 因此(unsigned long long)INT_MIN是一个非常大的正数,实际上是0xFFFFFFFF80000000 (To check this, add 0x80000000 to it to get 0 ). (要检查此项,请向其添加0x80000000以获得0 )。

So you are actually doing 0x7FFFFFFF | 0xFFFFFFFF80000000 所以你实际上在做0x7FFFFFFF | 0xFFFFFFFF80000000 0x7FFFFFFF | 0xFFFFFFFF80000000 which gives the observed result. 0x7FFFFFFF | 0xFFFFFFFF80000000 ,它给出了观察到的结果。


Later on it gets worse: 1 << 32 and larger causes undefined behaviour due to shifting by the whole width of the type. 后来它变得更糟: 1 << 32和更大导致由于移动类型的整个宽度而导致的未定义行为。

To fix this, change 0x1 in your code to 1ull . 要解决此问题,请将代码中的0x1更改为1ull The you will be shifting an unsigned long long , instead of an int . 你将转移一个unsigned long long ,而不是int

because of sign extension val is an unsigned long long. 因为符号扩展val是一个unsigned long long。 But val is not what you are shifting. 但是val不是你正在改变的。 You are shifting 0x1, an int, then extending it to long long for the '|=' 你正在转移0x1,一个int,然后将它扩展为long'for'| ='

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C++ 访问冲突读取位置 0xFFFFFFFFFFFFFFFF 在动态向量数组中 - C++ Access violation reading location 0xFFFFFFFFFFFFFFFF in dynamic array of vectors “myprogram.exe 中 0x000007FEFD5D7C8A(ole32.dll)处的未处理异常:0xC0000005:访问冲突读取位置 0xFFFFFFFFFFFFFFFF” - "Unhandled exception at 0x000007FEFD5D7C8A (ole32.dll) in myprogram.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF" 在 Elements.exe 中的 0x00007FF63C04254B 抛出异常:0xC0000005:访问冲突读取位置 0xFFFFFFFFFFFFFFFF - Exception thrown at 0x00007FF63C04254B in Elements.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF 运行时错误:基数为0x000000000000的指针索引表达式溢出到0xffffffffffffffffff以进行频率排序 - Runtime error: pointer index expression with base 0x000000000000 overflowed to 0xffffffffffffffff for frequency sort 访问冲突读取位置0xFFFFFFFFFFFFFFFFFF - Access violation reading location 0xFFFFFFFFFFFFFFFF 读取访问冲突,错误代码 0xFFFFFFFFFFFFFFFF - Read access violation, error code 0xFFFFFFFFFFFFFFFF Xmemory 访问冲突读取位置 0xFFFFFFFFFFFFFFFF - Xmemory Access violation reading location 0xFFFFFFFFFFFFFFFF “访问冲突读取位置 0xFFFFFFFFFFFFFFFF” 为什么我不能在函数中创建子类的 object? - "Access violation reading location 0xFFFFFFFFFFFFFFFF" Why can't I make an object of my child classes in functions? shmat(3) function 返回 0xffffffffffffffff 地址 - shmat(3) function returns 0xffffffffffffffff address 在 0x00007FF93E507A7A (ntdll.dll) 抛出异常。访问冲突读取位置 0xFFFFFFFFFFFFFFFF - Exception thrown at 0x00007FF93E507A7A (ntdll.dll) .Access violation reading location 0xFFFFFFFFFFFFFFFF
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM