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

时间:2021-05-26 12:01:04

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 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位const上的无符号移位。我想我的第一个声明会做一个有符号的右移。

I tried 0x800000000000000i64U and 0x800000000000000u64 but got compiler errors.

我尝试了0x8000000000000000000i64u和0x800000000000000000000000000u64,但是得到了编译错误。

3 个解决方案

#1


29  

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

您可以使用后缀ull,它是标准的(C99和c++ 0x)来指定一个无符号的长整数文字,并且一个长时间是至少64位。

#2


6  

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遍历以下类型(它没有后缀,所以它使用“无”行,它是十六进制常量,所以它使用“十六进制常量”列),它将使用第一个类型来存储该值*:

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

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

因此,要回答您的问题“我如何编写和使用值0x800000000000000并确保编译器不会将高比特视为符号位?”:只需编写无符号长长值= 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 int is 32-bits, long is 32-bits, and long long is 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位,long是32位,long是64位。注意,您的编译器可能对这些类型使用不同的位大小,这可能会改变最终结果(尽管过程仍然相同)。

#3


0  

Here is a way:

这是一个方法:

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

val1 = 8000000000000000 val2 = 7 fffffffffffffff val3 = 2000000000000000

#1


29  

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

您可以使用后缀ull,它是标准的(C99和c++ 0x)来指定一个无符号的长整数文字,并且一个长时间是至少64位。

#2


6  

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遍历以下类型(它没有后缀,所以它使用“无”行,它是十六进制常量,所以它使用“十六进制常量”列),它将使用第一个类型来存储该值*:

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

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

因此,要回答您的问题“我如何编写和使用值0x800000000000000并确保编译器不会将高比特视为符号位?”:只需编写无符号长长值= 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 int is 32-bits, long is 32-bits, and long long is 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位,long是32位,long是64位。注意,您的编译器可能对这些类型使用不同的位大小,这可能会改变最终结果(尽管过程仍然相同)。

#3


0  

Here is a way:

这是一个方法:

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

val1 = 8000000000000000 val2 = 7 fffffffffffffff val3 = 2000000000000000