C++ 你如何在 VS2008 中指定一个 64 位的 unsigned int const 0x8000000000000000?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2835746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:13:11  来源:igfitidea点击:

How do you specify a 64 bit unsigned int const 0x8000000000000000 in VS2008?

c++cvisual-studio

提问by franji1

I read about the Microsoft specific suffix "i64" for integer constants. I want to do an UNsigned shift to a ULONGLONG.
ULONGLONG bigNum64 = 0x800000000000000i64 >> myval;

我阅读了有关整数常量的 Microsoft 特定后缀“i64”的信息。我想做一个无符号转换到 ULONGLONG。
ULONGLONG bigNum64 = 0x800000000000000i64 >> myval;

In normal C, I would use the suffix "U", e.g. the similar 32 bit operation would be
ULONG bigNum32 = 0x80000000U >> myval;

在普通 C 中,我会使用后缀“U”,例如类似的 32 位操作将是
ULONG bigNum32 = 0x80000000U >> myval;

I do NOT want the 2's complement sign extension to propogate through the high bits. I want an UNSIGNED shift on a 64 bit const number. I think my first statement is going to do a SIGNED shift right.

我不希望 2 的补码扩展通过高位传播。我想要一个 64 位常量数字的无符号移位。我认为我的第一个语句将进行 SIGNED 右移。

I tried 0x800000000000000i64Uand 0x800000000000000u64but got compiler errors.

我试过了0x800000000000000i64U0x800000000000000u64但遇到了编译器错误。

回答by James McNellis

You can use the suffix ull, which is the standard (C99 and C++0x) way to specify an unsigned long longinteger literal, and a long longis at least 64 bits.

您可以使用后缀ull,这是指定unsigned long long整数文字的标准(C99 和 C++0x)方式,并且 along long至少为 64 位。

回答by Cornstalks

Funny enough, but you don't actually need to add any suffix to your hex constant in order for it to be treated correctly. Section 6.4.4.1 of the C standard and section 2.14.3 of the C++ standard contain the following table:

很有趣,但您实际上并不需要为您的十六进制常量添加任何后缀,以便正确处理它。C 标准的 6.4.4.1 节和 C++ 标准的 2.14.3 节包含下表:

Suffix       | Decimal Constant       | Octal or Hexadecimal Constant
-------------+------------------------+------------------------------
none         | int                    | int
             | long int               | unsigned int
             | long long int          | long int
             |                        | unsigned long int
             |                        | long long int
             |                        | unsigned long long int
-------------+------------------------+------------------------------
u or U       | unsigned int           | unsigned int
             | unsigned long int      | unsigned long int
             | unsigned long long int | unsigned long long int
-------------+------------------------+------------------------------
l or L       | long int               | long int
             | long long int          | unsigned long int
             |                        | long long int
             |                        | unsigned long long int
-------------+------------------------+------------------------------
Both u or U  | unsigned long int      | unsigned long int
and l or L   | unsigned long long int | unsigned long long int
-------------+------------------------+------------------------------
ll or LL     | long long int          | long long int
             |                        | unsigned long long int
-------------+------------------------+------------------------------
Both u or U  | unsigned long long int | unsigned long long int
and ll or LL |                        |

This table tells us what type an integer constant will have. The integer constant's type will be the first type in which it the value fits.

这张表告诉我们整数常量的类型。整数常量的类型将是该值适合的第一种类型。

This means that the compiler will iterate through the following types for the hexadecimal constant 0x800000000000000(it has no suffix, so it uses the "none" row, and it's a hex constant, so it uses the "Hexadecimal Constant" column), and it will use the first type which can store that value*:

这意味着编译器将为十六进制常量迭代以下类型0x800000000000000(它没有后缀,所以它使用“none”行,它是一个十六进制常量,所以它使用“十六进制常量”列),它会使用可以存储该值的第一种类型*:

  1. int: No, a 32-bit signed integer can't store this value.
  2. unsigned int: No, a 32-bit unsigned integer can't store this value.
  3. long int: No, a 32-bit signed integer can't store this value.
  4. unsigned long int: No, a 32-bit unsigned integer can't store this value.
  5. long long int: No, a 64-bit signed integer can't store this value.
  6. unsigned long long int: Yes, a 64-bit unsigned integer canstore this value. Since this is the first type that can fully store the value, this is the type that the integer constant will have.
  1. int: 不,一个 32 位有符号整数不能存储这个值。
  2. unsigned int: 不,一个 32 位无符号整数不能存储这个值。
  3. long int: 不,一个 32 位有符号整数不能存储这个值。
  4. unsigned long int: 不,一个 32 位无符号整数不能存储这个值。
  5. long long int: 不,64 位有符号整数不能存储这个值。
  6. unsigned long long int:是的,一个 64 位无符号整数可以存储这个值。由于这是第一种可以完全存储值的类型,因此这是整数常量将具有的类型。

So, to answer your question of "How can I write and use the value 0x800000000000000and make sure the compiler won't treat the high bit as a sign bit?": Simply just write unsigned long long value = 0x800000000000000.

因此,要回答“我如何编写和使用该值0x800000000000000并确保编译器不会将高位视为符号位?”的问题:只需编写unsigned long long value = 0x800000000000000.

If you want to do some bitwise arithmetic with the value, you can just go ahead and do that (i.e. just write 0x800000000000000 >> myval). You're guaranteed that it will not be treated as an overflowed signed integer, and your right shift won't do any sign extension because it's a positive value.

如果你想对这个值做一些按位算术,你可以继续这样做(即只写0x800000000000000 >> myval)。您可以保证它不会被视为溢出的有符号整数,并且您的右移不会进行任何符号扩展,因为它是一个正值。

*I'm assuming that intis 32-bits, longis 32-bits, and long longis 64-bits. Note that your compiler might use different bit sizes for these types, which may change the end result (though the process will still be the same).

*我假设它int是 32 位、long32 位和long long64 位。请注意,您的编译器可能对这些类型使用不同的位大小,这可能会改变最终结果(尽管过程仍然相同)。