divertido lo suficiente, pero que en realidad no necesita añadir ningún sufijo a su constante hexadecimal con el fin de debe ser tratado correctamente. Sección 6.4.4.1 de la norma C y la sección 2.14.3 de la norma C++ contiene la siguiente tabla:
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 | |
Esta tabla nos dice qué tipo una constante entera tendrá. El tipo de constante entera será el primer tipo en el que se ajuste el valor.
Esto significa que el compilador iterará a través de los siguientes tipos de la constante hexadecimal 0x800000000000000
(no tiene sufijo, por lo que utiliza la fila "ninguno" y es una constante hexadecimal, por lo que utiliza la columna "Constante hexadecimal"), y utilizará el primer tipo que puede almacenar ese valor *:
int
: no, un entero de 32 bits no puede almacenar este valor.
unsigned int
: No, un entero sin signo de 32 bits no puede almacenar este valor.
long int
: No, un entero con signo de 32 bits no puede almacenar este valor.
unsigned long int
: No, un entero sin signo de 32 bits no puede almacenar este valor.
long long int
: No, un entero con signo de 64 bits no puede almacenar este valor.
unsigned long long int
: Sí, un entero de 64 bits sin signo puede almacenar este valor. Como este es el primer tipo que puede almacenar completamente el valor, este es el tipo que tendrá la constante entera.
Por lo tanto, para responder a su pregunta de "¿Cómo puedo escribir y utilizar el valor 0x800000000000000
y asegúrese de que el compilador no sirve para tratar el bit alto como un bit de signo?": Simplemente acaba de escribir unsigned long long value = 0x800000000000000
.
Si desea hacer una aritmética bit a bit con el valor, puede continuar y hacer eso (es decir, simplemente escriba 0x800000000000000 >> myval
). Tiene la garantía de que no será tratado como un entero con signo desbordado, y su desplazamiento a la derecha no hará ninguna extensión de signo porque es un valor positivo.
* Estoy asumiendo que int
es de 32-bits, long
es de 32-bits, y long long
es de 64-bits. Tenga en cuenta que su compilador puede usar diferentes tamaños de bits para estos tipos, lo que puede cambiar el resultado final (aunque el proceso seguirá siendo el mismo).
En mi Visual Studio, 'limits.h' tiene la sintaxis' 0xffffffffffffffffui64', por lo que '0x800000000000000ui64' debería funcionar. Sin embargo, es una versión más nueva, por lo que tal vez no funcionó en Visual Studio 2008. – anatolyg
@MM: 'U' puede ser' unsigned int', 'unsigned long int', o' unsigned long long int' para un entero hexadecimal constante. 'UL' puede ser' unsigned long int' o 'unsigned long long int'. Ver 6.4.4.1 del estándar C (o 2.14.3 del estándar C++). Dado eso, no creo que el ejemplo del PO sea incorrecto o necesite modificación. – Cornstalks
Esta es una pregunta anterior. En C++ 11, no creo que sea necesario ningún sufijo. Solo un tipo integral sin signo de 64 bits puede contener esa constante. Un unsigned long long debe tener al menos 64 bits, y eso está en la lista de tipos que el compilador debe probar para un literal en formato hexadecimal. http://en.cppreference.com/w/cpp/language/integer_literal –