80 votes

Pas d'exception de dépassement pour les int en C# ?

J'ai eu cette expérience bizarre avec le problème numéro 10 sur Projet Euler (excellent site, d'ailleurs). La mission consistait à calculer la somme de tous les nombres premiers inférieurs à deux millions.

J'ai utilisé un int pour la somme, et mon algorithme a produit une réponse, mais lorsque je l'ai collé pour vérifier la réponse, elle était fausse.

Il s'est avéré que le résultat était trop grand pour tenir dans un int, mais cela ne provoquerait-il pas une erreur de dépassement de capacité ou autre ? Au lieu de cela, il a juste renvoyé une valeur très éloignée de la vraie réponse.

Quand j'ai changé le type en long, tout était parfait.

5 votes

Voulez-vous vraiment que chaque opération sur les nombres entiers vérifie le débordement ?

6 votes

Eh bien, cela m'aurait certainement fait gagner du temps dans ce cas précis ;)

1 votes

Dans ce cas, oui. Mais la grande majorité des opérations ne peuvent pas déborder. Il serait intéressant que le compilateur puisse le prouver et désactiver la vérification en conséquence, mais je doute fort qu'il le fasse.

111voto

Konrad Rudolph Points 231505

Les opérations sur les entiers en C# ne lèvent pas d'exceptions en cas de dépassement par défaut. Vous pouvez y parvenir via les paramètres du projet, ou en effectuant le calcul suivant checked :

int result = checked(largeInt + otherLargeInt);

Maintenant, l'opération sera lancée.

Le contraire est unchecked qui rend toute opération explicitement non vérifiée. Évidemment, cela n'a de sens que si vous avez activé les opérations cochées dans les paramètres du projet.

0 votes

Sauf si vous êtes en mode débogage, où je pense que les opérations int sont vérifiées par défaut.

8 votes

Non. J'étais en mode débogage quand ça s'est produit.

0 votes

Oh. Je me suis trompé. J'étais sûr que mes projets Euler m'avaient parlé des débordements en mode débogage. :/

27voto

0xA3 Points 73439

En C#, un OverflowException n'est pas déclenchée (en VB, l'exception est déclenchée par défaut).

Pour obtenir l'exonération, vous devez intégrer votre code dans un fichier de type checked le contexte :

byte value = 241;
checked
{
    try 
    {
        sbyte newValue = (sbyte) value;
        Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", 
            value.GetType().Name, value, 
            newValue.GetType().Name, newValue);
    }
    catch (OverflowException) 
    {
        Console.WriteLine("Exception: {0} > {1}.", value, SByte.MaxValue);
    }
}       

MSDN l'explique plus en détail :

Pour que l'opération arithmétique, de coulage ou de conversion pour qu'une opération d'arithmétique, de coulage ou de conversion déclenche une OverflowException, l'opération doit se produire dans un contexte vérifié. Par défaut, les opérations arithmétiques et les débordements en Visual Basic sont vérifiés ; en C#, ils ne le sont pas. Si l'opération se produit dans un contexte non vérifié, le résultat résultat est tronqué en supprimant tous les bits bits de poids fort qui ne rentrent pas dans le type de destination.

9voto

Andreas Niedermair Points 8907

J'ai déjà ajouté un commentaire, mais peut-être que cela intéressera certains d'entre vous :

msdn nous dit :

Débordement arithmétique d'un nombre entier déclenche une OverflowException ou élimine les bits les plus significatifs du résultat

mais

Le dépassement arithmétique décimal est toujours déclenche une OverflowException.

également

Lorsque le dépassement d'un nombre entier se produit, ce qui ce qui se passe dépend du contexte d'exécution d'exécution, qui peut être vérifié ou décoché. Dans un contexte vérifié, une OverflowException est lancée. Dans un contexte contexte non vérifié, l'erreur la plus bits les plus significatifs du résultat sont sont éliminés et l'exécution se poursuit. Ainsi, C# vous donne le choix entre gérer ou ignorer le débordement.

1 votes

Ce qui est logique, puisque les décimales sont principalement utilisées pour les calculs monétaires ou scientifiques, et que vous préféreriez probablement qu'elles soient jetées plutôt que d'échouer silencieusement.

6voto

Thorarin Points 21538

Par défaut, C# ne vérifie pas le débordement arithmétique des entiers. Vous pouvez changer cela avec l'option /checked option de compilation ou en activant "Check for arithmetic overflow/underflow" dans Visual Studio (propriétés du projet - Build - Advanced).

Vous pouvez utiliser checked et unchecked mots-clés pour remplacer la valeur par défaut au cas par cas. Si vous comptez sur le fait que la vérification a lieu dans un morceau de code, l'activer explicitement en utilisant la fonction checked serait une bonne idée.

int j = checked(i * 2);

checked
{
    int j = i * 2;
    // Do more stuff
}

Notez que les opérations en virgule flottante ne lèvent jamais un OverflowException et les opérations décimales génèrent toujours un OverflowException . Voir aussi Opérateurs C# .

-3voto

Restuta Points 4476

Le dépassement d'un int ne peut pas provoquer d'exception par lui-même, mais il peut être provoqué par un autre code, qui porte sur la variable qui contiendra le résultat du dépassement.

Modifié : Désolé pour cette réponse si rapide et mauvaise, je voulais dire que l'ajout ne peut pas causer d'exception par défaut. Seulement avec vérifié .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X