2010-05-29 9 views
33

¿Qué pasa con esto, de todos modos? Hago una simple multiplicación:¿No debería esto causar un desbordamiento? ¡No lo hace!

Int64 x = 11111111111; 
Int64 y = 11111111111; 
Int64 z = x * y; 

Y al final de la multiplicación, z muestra un valor de:

-5670418394979206991

Esto se ha desbordado con claridad, pero se plantea no es una excepción. Me gustaría que uno se críe, pero ...

Tenga en cuenta que esto es en Windows Phone 7, pero no creo que esto tenga relación con el problema. O lo hace?

Respuesta

43

Se puede utilizar un bloque de comprobar como se ha señalado ya por otras respuestas:

checked 
{ 
    long x = 11111111111; 
    long y = 11111111111; 
    long z = checked(x * y); 
    // ... 
} 

que da lugar a una excepción:

OverflowException: operación aritmética dio lugar a un desbordamiento.

Si se acaba de hacer una sola operación en la que es necesario que la comprobación se puede utilizar una vez checked expression:

long x = 11111111111; 
long y = 11111111111; 
long z = checked(x * y); 

También puede establecer la /checked compiler option tener comprobarse el valor predeterminado.

Para establecer esta opción del compilador en el entorno de desarrollo de Visual Studio:

  1. Abrir cuadro de diálogo Páginas de propiedades del proyecto. Para más detalles, vea Setting Visual C# Project Properties.
  2. Haga clic en Configuración Propiedades carpeta.
  3. Haga clic en la Build página de propiedades.
  4. Modifique Compruebe la propiedad de desbordamiento/desbordamiento aritmético.

Si cambia el valor por defecto de marcado puede utilizar bloques sin marcar, o expresiones para obtener el comportamiento sin marcar de nuevo.

+25

Tenga en cuenta que la razón por la que no se selecciona es la predeterminada porque (1) el 99% de las veces la aritmética entera no está cerca de los límites, y (2) la aritmética comprobada es MUCHO más lenta. Este es uno de los pocos casos en que el diseño de C# elige peligrosamente por defecto por motivos de rendimiento. –

+0

El jitter x86 usa un jno simple, la predicción de bifurcación siempre es buena, no puede costar más que un solo ciclo. –

+0

No es necesariamente relevante para el diseño de C#, pero en este caso específico estamos hablando de ARM. El comportamiento del jitter x86 es algo académico – Stewart

26

Check it:

checked 
{ 
    Int64 x = 11111111111; 
    Int64 y = 11111111111; 
    Int64 z = x * y; 
} 
+6

¡Bingo! Aprende algo nuevo todos los días, ¡lo hago! Gracias. Y gracias a Dios por SO. – Cyberherbalist

8

Probar:

checked 
{ 
    Int64 x = 11111111111; 
    Int64 y = 11111111111; 
    Int64 z = x * y; 
} 
8

compilador supone que desea hacerlo de esa manera y continuar con el desbordamiento. Si el desbordamiento debe considerarse como una excepción para la operación, ajuste la operación alrededor de checked y emitirá una excepción en el tiempo de ejecución.

checked 
{ 
    Int64 x = 11111111111; 
    Int64 y = 11111111111; 
    Int64 z = x * y; 
} 

System.OverflowException: Una excepción de tipo System.OverflowException fue lanzado .

Cuestiones relacionadas