¿El tipo predeterminado de la constante entera está firmado o no?

4 minutos de lectura

avatar de usuario
Víctor S.

¿El tipo predeterminado de la constante entera está firmado o no? como 0x80000000, ¿cómo puedo decidir usarlo como una constante entera con signo o una constante entera sin signo sin ningún sufijo?

Si es una constante entera con signo, ¿cómo explicar el siguiente caso?

printf("0x80000000>>3 : %x\n", 0x80000000>>3);

producción:

0x80000000>>3 : 10000000

El siguiente caso puede indicar que mi plataforma utiliza un cambio de bit aritmético, no un cambio de bit lógico:

int n = 0x80000000;

printf("n>>3: %x\n", n>>3);

producción:

n>>3: f0000000

  • Generalmente, 0x80000000 es INT_MAX + 1, por lo que no está firmado. De ahí el cambio lógico en el primer ejemplo. Pero cuando lo asignas a un intinvoca un comportamiento indefinido y, por lo general, el resultado es INT_MIN. El desplazamiento a la izquierda de enteros negativos está definido por la implementación, a menudo se utiliza el desplazamiento aritmético. La diferencia es que en este último lo fuerza a un tipo firmado.

    –Daniel Fischer

    3 de julio de 2012 a las 12:28

  • @DanielFischer INT_MAX + 1 es UB pero int n = 0x80000000; no es UB pero está definido por la implementación y la conversión de enteros en este caso se rige por 6.3.1.3p3 (en C99)

    – ouah

    3 de julio de 2012 a las 18:54

  • @ouah El INT_MAX + 1 fue pensada como una expresión matemática, no C. Sin embargo, es correcto convertir eso a int no es un comportamiento indefinido, sino una implementación definida. Mi error.

    –Daniel Fischer

    3 de julio de 2012 a las 18:57

C tiene diferentes reglas para constantes decimales, octales y hexadecimales.

Para decimal, es el primer tipo en el que puede caber el valor: int, long, long long

Para hexadecimal, es el primer tipo en el que puede caber el valor: int, unsigned int, long, unsigned long, long long, unsigned long long

Por ejemplo, en un sistema con 32-bit int y unsigned int: 0x80000000 es unsigned int.

Tenga en cuenta que para las constantes decimales, C90 tenía reglas diferentes (pero las reglas no cambiaron para las constantes hexadecimales).

  • La única respuesta correcta hasta ahora. (Nits: no especificaste las reglas para octal [see hex]y de C90, literales hexadecimales cambiados por la adición de la long long tipos).

    –Daniel Fischer

    3 de julio de 2012 a las 12:14

  • pero entonces no podemos esperar una advertencia en int n = 0x80000000; ¿Porque está asignando un uint32_t a un int32_t y de alguna manera se desborda?

    – mbonnin

    3 de julio de 2012 a las 12:29

  • ¿Significa esto la declaración “Una constante entera como 1234 es un int”. en [K&R2] ¿Está Mal?

    – Víctor S.

    3 de julio de 2012 a las 12:37

  • @VictorS: No, es correcto: 1234 está dentro del rango mínimo garantizado de int por lo que siempre tendrá tipo int.

    – café

    3 de julio de 2012 a las 13:12

  • @mbonnin algunos compiladores lata mostrar una advertencia, pero el estándar no requiere una advertencia. Hay conversiones implícitas entre cualquier tipo aritmético a cualquier tipo aritmético.

    – ouah

    3 de julio de 2012 a las 13:20

avatar de usuario
graham borland

esta firmado si cabe en un entero con signo. Para que no esté firmado, agregue un u sufijo, por ejemplo 1234u.

Puede convertir un valor con signo a sin signo asignándolo a una variable sin signo.

unsigned int i = 1234u; // no conversion needed
unsigned int i = 1234;  // signed value 1234 now converted to unsigned

Para 0x80000000será no firmado si los ints son de 32 bits en su plataforma, ya que no caben en un int firmado.


Sin embargo, otra cosa a tener en cuenta es que el comportamiento del desplazamiento a la derecha depende de la plataforma. En algunas plataformas se conservan los signos (aritmética) y en algunas plataformas es un simple desplazamiento bit a bit (lógico).

  • Actualizado para responder a su consulta adicional.

    –Graham Borland

    3 de julio de 2012 a las 12:11

  • 0x80000000 no está firmado pero no está firmado en sistemas de 32 y 64 bits.

    – ouah

    3 de julio de 2012 a las 12:11

  • Está firmado si cabe en un entero con signo Creo que esta afirmación es incorrecta.

    – ouah

    3 de julio de 2012 a las 12:15

  • Una constante entera decimal siempre tiene signo. Para constantes hexadecimales, puede caber en un long pero si cabe en un unsigned int será unsigned int. Un entero con signo no es sinónimo de un entero con signo int. El tipo long es también un tipo entero con signo.

    – ouah

    3 de julio de 2012 a las 12:20

  • ¿Qué sucede en la conversión? ¿De firmado a sin firmar?

    – Suraj Jain

    30 de diciembre de 2016 a las 17:17

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad