2010-05-03 12 views
15

He leído en muchos lugares que el desbordamiento de enteros está bien definido en C a diferencia de la contraparte firmada.Pregunta sobre el comportamiento de C para el flujo insuficiente de enteros sin signo

¿El subdesbordamiento es el mismo?

Por ejemplo:

unsigned int x = -1; // Does x == UINT_MAX? 

Gracias.

No puedo recordar dónde, pero he leído que la aritmética en los tipos integrales sin signo es modular, por lo que si ese fuera el caso, entonces -1 == UINT_MAX mod (UINT_MAX + 1).

+2

Creo que el término "underflow" solo es realmente aplicable a los números de coma flotante, donde no se pueden representar algunos números muy cercanos a cero. Los enteros no tendrían este problema. – WildCrustacean

+0

@bde Estoy de acuerdo en que es una declaración técnicamente precisa, pero el término a menudo está sobrecargado por la violación de la condición de frontera en el extremo inferior de un sistema numérico. – vicatcu

Respuesta

22

§6.2.5, párrafo 9:

Un cálculo que implica sin signo operandos nunca puede desbordamiento, porque un resultado que no puede ser representado por el tipo entero sin signo resultante se reducido módulo el número que es uno mayor que el valor más grande que se puede representar por el tipo resultante .

Editar:

Lo sentimos, la referencia equivocada, pero el resultado sigue siendo inmovilizada. La referencia correcta es §6.3.1.3 (firmado y la conversión entero sin signo):

si el nuevo tipo es sin signo, el valor se convierte por adición o sustracción de uno más que el valor máximo en repetidas ocasiones que puede estar representado en el nuevo tipo hasta el valor está en el rango del nuevo tipo .

Así que sí, x == UINT_MAX.

+0

Su referencia es correcta, pero no aplicable, ya que la expresión -1 implica operandos con signo, no operandos sin signo. –

+0

La pregunta ya admite que el desbordamiento está bien definido. La pregunta es sobre números negativos, no positivos. –

+0

@Doug, @Mark: la pregunta es acerca de las conversiones de enteros a enteros sin signo, que se especifica en §6.3.1.3. –

4

-1, cuando se expresa como un número de complemento de 2, equivale a 0xFF ... F por cuantos bits hay en su número. En un espacio numérico sin signo, ese valor es el valor máximo posible (es decir, todos los bits están configurados). Por lo tanto, sí, x == UINT_MAX. El siguiente código emite "1" en un compilador estricto C99:

#include <stdio.h> 
#include <stdint.h> 
#include <limits.h> 

int main(int argc, char **argv){ 
    uint32_t x = -1;  
    printf("%d", x == UINT_MAX ? 1 : 0); 
    return 0; 
} 
+1

¿Hay dos números de complemento requeridos por el estándar? –

+4

No, el complemento no requiere 2 segundos, por lo que esta solución no es general; ver mi respuesta –

+1

No es necesario que el valor máximo de 'uint32_t' sea' UINT_MAX' - 'UINT_MAX' puede ser tan pequeño como 65535 y tan grande como' ULONG_MAX'. Si cambia ese 'uint32_t' a' unsigned' será correcto. – caf

-1

Está mezclando números con y sin signo, lo que no es bueno.

unsigned int x = 0u - 1u; // is OK though 
+3

Puede o no ser poco frío, pero está perfectamente definido. Conforme al estándar. C. –

+0

@Stephen Canon, Untrue. La representación bit a bit de -1 no está definida. Podría ser el complemento, por ejemplo. –

+0

@Stepen, "compatible con el estándar" ¿tal vez, pero "bien definido"? Ese es el quid de la cuestión. –

Cuestiones relacionadas