2010-05-29 5 views
33

Quoi de neuf avec ça, quand même? Je fais une simple multiplication:Cela ne devrait-il pas provoquer un débordement? Ce n'est pas le cas!

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

Et à la fin de la multiplication, z représente une valeur de:

-5670418394979206991

Cela a clairement débordé, mais aucune exception est soulevée. J'aimerais que l'un d'entre eux soit surélevé, mais ...

Notez que c'est sur Windows Phone 7, mais je ne pense pas que cela ait une influence sur le problème. Ou est-ce?

Répondre

43

Vous pouvez utiliser un bloc vérifié comme l'ont déjà signalé par d'autres réponses:

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

qui se traduit par une exception:

OverflowException: opération arithmétique a donné lieu à un trop-plein.

Si vous faites juste une seule opération où vous devez vous vérifier pouvez utiliser un checked expression à la place:

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

Vous pouvez également définir la /checked compiler option d'avoir la valeur par défaut est cochée.

Pour définir cette option du compilateur dans l'environnement de développement Visual Studio:

  1. Ouvrir Pages de propriétés boîte de dialogue du projet. Pour plus de détails, voir Setting Visual C# Project Properties.
  2. Cliquez sur le dossier Configuration Properties. Cliquez sur la Build page de propriétés.
  3. Modifier la propriété Vérifier la propriété Arithmétique Overflow/Underflow.

Si vous modifiez la valeur par défaut pour vous vérifié pouvez utiliser des blocs ou des expressions non vérifiées pour obtenir à nouveau le comportement incontrôlé.

+25

Notez que la raison pour laquelle cette case n'est pas cochée est la suivante: (1) 99% de l'arithmétique des nombres entiers ne sont pas proches des limites et (2) l'arithmétique vérifiée est WAY plus lente. C'est l'un des rares cas où la conception de C# choisit dangereux par défaut pour des raisons de performances. –

+0

La gigue x86 utilise un jno simple, la prédiction de branche est toujours bonne, ne peut pas coûter plus d'un seul cycle. –

+0

Ce n'était pas nécessairement pertinent pour la conception de C#, mais dans ce cas précis, nous parlons d'ARM. Le comportement de la gigue x86 est un peu académique – Stewart

26

Check it:

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

Bingo! Apprenez quelque chose de nouveau chaque jour, je le fais! Merci. Et Dieu merci pour SO. – Cyberherbalist

8

Essayez:

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

compilateur suppose que vous voulez le faire de cette façon et procéder au débordement. Si le débordement doit être considéré comme une exception pour l'opération, enroulez l'opération autour de checked et une exception sera émise lors de l'exécution.

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

System.OverflowException: Une exception de type System.OverflowException était jeté.

Questions connexes