如何在VS2008中指定64位无符号int const 0x8000000000000000?

我读了关于整数常量的Microsoft特定后缀“i64”。 我想做一个UNSLigned转到ULONGLONG。
ULONGLONG bigNum64 = 0x800000000000000i64 >> myval;

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

我不希望2的补码符号扩展通过高位传播。 我想在64位常数上进行UNSIGNED转换。 我认为我的第一个声明是要做一个SIGNED右移。

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

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

有趣的是,你实际上并不需要为你的hex常量添加任何后缀,以便正确处理它。 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 | | 

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

这意味着编译器将迭代hex常量0x800000000000000的以下类型(它没有后缀,因此它使用“none”行,并且它是hex常量,因此它使用“hex常量”列),并且它将使用可以存储该值的第一种类型*:

  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位无符号整数可以存储该值。 由于这是第一种可以完全存储值的类型,因此这是整数常量所具有的类型。

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

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

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

这是一种方式:

 int main() { uint64_t val1=0x1p63; //1 * 2**63 uint64_t val2=((uint64_t)0x1p63)-1; //0x1p63 is a float constant uint64_t val3= ((uint64_t)0x1p63) >> 2; cout << hex << "val1=" << val1 << " val2=" << val2 << " val3=" << val3 << endl; return 0; } 

val1 = 8000000000000000 val2 = 7fffffffffffffff val3 = 2000000000000000