2012-05-17 23 views
5

Quiero poder usar números enteros positivos grandes (8 bytes) en mi proyecto, aunque sizeof (unsigned long) rinde 8 en mi sistema, lo leí en la mayoría de los sistemas sin firmar de larga duración tienen solo 4 bytes y decidí dar unsigned long long a go, ya que se garantiza que tendrá al menos 8 bytes.unsigned long long vs unsigned long (portabilidad punto de vista)

Cuanto más lo uso, vi que no es súper portátil también, por ejemplo en algunos sistemas (según el compilador) printf lo formatea con% llu, en algunos lo formatea con% lld.

Mi código solo se ejecutará en máquinas Debian de 64 bits, en las cuales la longitud sin signo será de 8 bytes. La portabilidad no es un gran problema. ¿Es excesivo usar largos largos sin firmar sobre largos sin firmar en estas circunstancias? ¿Hay algún otro beneficio de usar largos largos sin signo sobre largos sin signo?

+7

¿Has probado 'uint64_t'? Está en ' .' – Mysticial

+0

¿cuál es la ventaja de usarlo durante mucho tiempo sin firmar? –

+1

Se detiene la compilación si no tiene ningún tipo con exactamente 64 bits mientras largo largo a lo largo de tipo más largo. Ambos están presentes en C++ 11, ambos están a menudo presentes como extensión anterior, pero no me sorprendería que uno estuviera a veces presente y no el otro.Si no lo tiene, stdint.h es más fácil de emular (suponiendo que el tipo está presente) que mucho tiempo. – AProgrammer

Respuesta

9

unsigned long long garantiza que tiene al menos 64 bits, independientemente de la plataforma. (Hay plataformas donde es más — Sé de 72 bits y 96 bits — pero son raros, y decididamente exóticos.) unsigned long se garantiza que será al menos de 32 bits. Si necesita más de 32 bits, le recomendaría unsigned long long.

Con respecto al formateo, con printf, debe usar "%llu" (ya que no tiene signo); "%lld" es para signed long long.

+0

gracias James, eso es lo que pensé, definitivamente es más seguro usar unsigned long. Sin embargo, esta es la pregunta, ya que en mi entorno de desarrollo y destino, el largo sin signo es de 8 bytes, ¿puedo simplemente usar el largo sin signo? Por cierto, el compilador lanza una advertencia cuando uso% llu con unsigned long long, este tipo de no portabilidades me asustan de usar unsigned long long. –

+0

¿La garantía de "al menos 64 bits" no está disponible solo desde C++ 11? – juanchopanza

+0

@erinc Si está trabajando en una plataforma donde tanto 'long long' como' long' tienen el mismo tamaño, el código generado debería ser idéntico para ellos, por lo que no hay razón para no usar 'long long'. Y si el compilador advierte al pasar un 'unsigned long long' a un' "% llu" ', esto solo se puede considerar un error. El único tipo legal para pasar a '"% llu "' es 'unsigned long long'; pasar cualquier otro tipo es un comportamiento indefinido. –

0

Si necesita asegurarse de tener un tamaño fijo del valor entero, independientemente de la plataforma, puede usar la biblioteca boost :: integers (consulte here). Puede usar boost :: int64_t o boost :: uint64_t para valores sin firmar

+0

¿por qué usar boost y no stdint.h uint64_t? – WeaselFox

0

Usted puede hacer esto si desea quedarse con largo y largo, largo:

#include <limits.h> 
#if ULONG_MAX >= 0xFFFFFFFFFFFFFFFFULL 
typedef unsigned long uint64; 
#else 
typedef unsigned long long uint64; 
#endif 

w.r.t. este

en algunos sistemas (dependiendo del compilador) printf formatea con llu%, en algunos se formatea con LLD%

printf() no adivina el formato. Usted le dice el formato.

Si desea printf un uint64 definido como en lo anterior, hacerlo de esta manera:

printf("%llu", (unsigned long long)some_uint64_value);

Usted puede typedef unsigned long long ulonglong; para hacer el reparto más fácil de escribir.

Existen otras formas de hacer lo mismo, pero no todos los compiladores las admiten. Es por eso que adjunté el sufijo ULL al número. En algunos modos de compatibilidad entre C89 y C99, 0xFFFFFFFFFFFFFFFF se puede interpretar como unsigned long, no unsigned long long, y se truncarán. El último gcc se ejecuta por defecto en el modo gnu89 para el código C, no en c99 o superior.