2010-09-01 19 views
46

En C# veo que-1 * int.MinValue == int.MinValue ?? ¿Es esto un error?

-1 * int.MinValue == int.MinValue 

Es esto un error? Realmente me fastidió cuando estaba tratando de implementar un árbol de búsqueda. Terminé usando (int.MinValue + 1) para poder negarlo correctamente.

+5

+1 Pregunta muy interesante y divertida: D – Jonathan

+1

Esta es una de esas cosas que realmente no entiendo, ¿Por qué C# no está marcado por defecto? – Aelphaeis

Respuesta

57

Esto no es un error.

int.MinValue * -1 es 1 mayor que int.MaxValue puede contener. Por lo tanto, el número vuelve a int.MinValue.

Esto es causado básicamente por un desbordamiento de enteros.

Int32.MinValue:

El valor de esta constante es -2,147,483,648

Int32.MaxValue:

El valor de esta constante es 2,147,483,647

Entonces, -2,147,483,648 * -1 = 2,147,483,648 que es 1 mayor que Int32.MaxValue.

+1

¡la matemática entera es tan coool! ;) –

+1

@Mark, en este caso, creo que no es genial. Es confuso. – jjnguy

+0

Depende de cómo lo mires. Desde una perspectiva bit a bit con '-x: = ~ x + 1' y' Int32.MinValue' siendo '1000 0000 0000 0000 0000 0000 0000 0000' en realidad es bastante plausible. Y el '32' en 'Int32' apunta exactamente hacia esa dirección :) – back2dos

9

No es un error, es un desbordamiento.

En la representación two's complement, el espacio de los números representables no es simétrico. Lo opuesto al entero más pequeño no se puede representar. La computación se desborda y le da el mismo número nuevamente.

+7

por menos de un segundo, pensé que dirías que no es un error, es una característica. : D – Jonathan

8
int i = -1 * int.MinValue; 

esto ni siquiera compilar menos que se desactive la comprobación:

error CS0220: The operation overflows at compile time in checked mode 
+0

Solo quería observar que el modo verificado está aparentemente deshabilitado de manera predeterminada.http: //msdn.microsoft.com/en-us/library/h25wtyxf.aspx – Aelphaeis

2

No, no es un error. Es la naturaleza de la aritmética de números enteros del complemento dos.

Por ejemplo, tomemos un valor de byte con signo que va entre -128 y 127.

127(0x7f)+1 = 128(0x80). Sin embargo, 0x80 es, de hecho, la representación binaria de -128.

Así, por un byte, 128(0x80) = -128(0x80)

Así -128(0x80) * -1 = 128(0x80) = -128(0x80)

2

Deja una región marcada en él y ver el "error" evolucionar hacia una excepción. O pruebe VB.NET (que, por lo que recuerdo, está marcado por defecto a diferencia de C#).

+0

+1 para mencionar el estado comprobado. – Aelphaeis

Cuestiones relacionadas