2010-06-08 17 views
5

Lo sé, Int32.MaxValue * Int32.MaxValue dará un número mayor que Int32; Pero, ¿esta afirmación no debería generar algún tipo de excepción?¿Por qué Int32.MaxValue * Int32.MaxValue == 1?

Me encontré con esto al hacer algo como IF (X * Y > Z) donde todos son Int32. X y Y son lo suficientemente grandes como para obtener un valor falso de X * Y.

¿Por qué es así y cómo evitar esto? además de enviar todo al Int64.

+0

¿Es esto en un bloque 'unchecked'? – Skywalker

+0

Ver http://stackoverflow.com/questions/2363838/when-must-we-use-checked-operator-in-c –

Respuesta

6

ha desactivado los controles de desbordamiento en su proyecto. Con el modo comprobado encendido lanzará una excepción.

+0

¡gracias por tus respuestas! No deshabilité la verificación de desbordamiento; ¿Dónde está esta configuración en Visual Studio? –

+0

No tengo una copia de VS aquí pero si recuerdo bien está en las opciones del compilador Avanzado (haga clic con el botón derecho en un proyecto y luego Propiedades -> Compilar -> Avanzado) – munissor

19

De forma predeterminada, la aritmética de C# se realiza en un contexto no verificado, lo que significa que los valores se transferirán.

Puede usar el checked and unchecked keywords para controlar ese comportamiento.

+0

Simplemente se ejecutó en un escenario donde int.maxvalue + 1 era int.minvalue ...¡Estaba rascándome la cabeza con tanta fuerza hasta que me di cuenta de que debía estar rodando! – richard

6

usted tiene que preguntar por ella:

checked { 
    int a = int.MaxValue; 
    int b = int.MaxValue; 
    int c = a * b; // kaboom 
} 
26

Debido confines Int32 resultados a 32bits.

Por lo tanto, si tiene un vistazo a las matemáticas en un nivel de byte.

FFFFFFFF * FFFFFFFF = FFFFFFFE00000001 

Como se puede ver, los 4 bytes más bajos = 1.

2

Int32.MaxValue (usando el valor dado here) es 2,147,483,647.

En la base 2, es decir: 111 1111 1111 1111 1111 1111 1111 1111 ... 2^31-1. El primer bit es el bit de signo.

Si usted multiplica eso por sí mismo, que se obtiene: 11 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0001

Volviendo al problema original de "¿por qué es 1?", Ya que Integer.MaxValue es el valor máximo, que provoca un desbordamiento de enteros. El resultado se trunca a los 31 bits más bajos, que son todos 0s más 1.

Editar: Aquí está a tutorial en la multiplicación binaria. El uso de un simple caso de todos los 1s: * 111

que se obtiene: + 11100 = 100001

Se puede ampliar esto para el caso de Int32.MaxValue. Lo acorté a 3 dígitos por brevedad.

Además, como dijo otra respuesta, en C# estos desbordamientos ocurrirán por defecto.

+0

Un buen tratamiento para los que lo necesitan, ¿pero? el OP se preguntaba por qué C# no lo atrapó y arrojó un error. – BCS

8

Es interesante notar que esto funciona independientemente de la base que utilice:

(n-1)*(n-1) mod n 
n^2 - 2n + 1 mod n 
0 - 0 + 1 mod n 
      1 mod n 
Cuestiones relacionadas