2011-02-26 18 views
13

Mis disculpas si la pregunta parece extraña. Estoy depurando mi código y este parece ser el problema, pero no estoy seguro.Cómo convertir o convertir un int sin firmar a int en C?

Gracias!

+1

La verdadera pregunta es qué quiere hacer cuando/si el valor en el sin signo lo encuentra fuera del rango que puede representarse con un int firmado. Si está dentro del alcance, simplemente asíguelo y listo. Si está fuera de rango, dará un resultado no especificado, por lo que probablemente querrá reducirlo primero al rango correcto o asignarlo a un tipo firmado más grande. –

+0

No especificado, definido por la implementación (C99 6.3.1.3§3). De lo contrario, estoy de acuerdo, y la asignación a un int más grande firmado es la solución más fácil. – Gauthier

Respuesta

23

Depende de lo que desea que el comportamiento sea. Un int no puede contener muchos de los valores que un unsigned int puede.

Puedes lanzar como de costumbre:

int signedInt = (int) myUnsigned; 

pero esto va a causar problemas si el valor es unsigned más allá del máximo int puede contener. Esto significa que la mitad de los posibles valores unsigned darán como resultado un comportamiento erróneo a menos que lo vigile específicamente.

Probablemente debería volver a examinar cómo almacena los valores en primer lugar si tiene que realizar la conversión sin un buen motivo.

EDIT: Según lo mencionado por ProdigySim en los comentarios, el valor máximo depende de la plataforma. Pero puede acceder a él con INT_MAX y UINT_MAX.

Para los habituales tipos de 4 bytes:

4 bytes = (4*8) bits = 32 bits 

Si se utilizan los 32 bits, como en unsigned, el valor máximo será de 2^32 - 1 o 4,294,967,295.

Un int firmado sacrifica de hecho un bit por el signo, por lo que el valor máximo será 2^31 - 1 o 2,147,483,647. Tenga en cuenta que esto es la mitad del otro valor.

+0

¿Sabes cuál es el valor máximo para un unsigned? y para un int? –

+1

@Eric Brotto: Va a depender del sistema para el que está compilando. Por lo general, hay macros disponibles para INT_MAX, UINT_MAX si necesita verificar. En la mayoría de los sistemas de 32 bits, INT_MAX va a ser (2^31) -1 y UINT_MAX es (2^32) -1. Tenga en cuenta que UINT_MAX emitido como int será -1. – ProdigySim

+2

"Normalmente" en el sentido que el estándar C los requiere (para un sistema alojado). –

2

Si tiene una variable unsigned int x;, puede convertirla a int usando (int)x.

1

Es tan simple como esto:

unsigned int foo; 
int bar = 10; 

foo = (unsigned int)bar; 

O viceversa ...

+3

El yeso es redundante y feo. La asignación incluye inherentemente la conversión en C para los tipos en los que la asignación tiene sentido (e incluso para algunos en los que no). Los moldes generalmente sirven para encubrir un código incorrecto. –

+2

Eso no es cierto, este es en realidad un problema bastante común si está revisando para ver si ha transcurrido un cierto tiempo. Su intervalo debe ser un entero sin signo, ya que no tiene sentido que se firme, pero time_t siempre se firma para que pueda representar fechas anteriores a 1970. Si no hace un molde al hacer si ((ahora - luego) intervalo) el compilador generará advertencias. –

2

int sin signo puede ser convertido a la firma (o viceversa) mediante la simple expresión, como se muestra a continuación:

unsigned int z; 
int y=5; 
z= (unsigned int)y; 

Aunque no se dirige a la pregunta, que le gustaría leer siguientes enlaces:

+1

Creo que quisiste decir "z = (unsigned int) y;" en la expresión de arriba Como y ya es int, convertirlo en int es algo sin sentido ... –

+0

Sí ......... :) –

0

Si un int int y un (firmado) sin signo se utiliza de la misma expresión, el int firmado se convierte implícitamente a firmar. Esta es una característica bastante peligrosa del lenguaje C y, por lo tanto, es necesario tenerlo en cuenta. Puede o no ser la causa de tu error. Si desea una respuesta más detallada, tendrá que publicar algún código.