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

J'ai eu cette expérience étrange avec le problème numéro 10 sur Projet Euler (excellent site au fait). L'affectation était de calculer la somme de tous les nombres premiers en dessous de deux millions.

J'ai utilisé un int pour la somme, et mon algorithme produit une réponse, mais quand je l'ai collé à vérifier la réponse, c'était mal.

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ébordement ou quelque chose? Au lieu de cela, il a juste renvoyé une valeur lointaine de la vraie réponse.

Quand j'ai changé le type à long, tout était hunky dory.

50
demandé sur Zero Piraeus 2010-01-13 15:09:54

5 réponses

Les opérations c # integer ne lancent pas d'exceptions en cas de débordement par défaut. Vous pouvez y parvenir via les paramètres du projet, ou en faisant le calcul checked:

int result = checked(largeInt + otherLargeInt);

Maintenant, l'opération va lancer.

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

76
répondu Konrad Rudolph 2010-01-13 12:11:29

En C# une OverflowException n'est pas levée (en VB de l'exception est levée par défaut).

Pour obtenir l'excpetion vous devez intégrer votre code dans un checked 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 explique plus en détail:

Pour l'arithmétique, la coulée, ou opération de conversion pour lancer un OverflowException, l'opération doit se produire dans un activée contexte. Par par défaut, opérations arithmétiques et les débordements dans Visual Basic sont vérifiés; en C#, ils ne le sont pas. Si l'opération se produit dans un contexte décoché, le le résultat est tronqué en rejetant tout bits d'ordre Élevé qui ne rentrent pas dans le type de destination.

19
répondu Dirk Vollmar 2010-01-13 12:13:53

C'est parce que, par défaut C# ne lance aucune exception pour le débordement entier ainsi que le sous-flux. Il y a quelques choses que vous pouvez faire ici.

Option 1

, Vous devez activer l'exception levée par aller à Projet => propriétés => onglet Build => Avancé => vérifier l'arithmétique de dépassement de dépassement de capacité.(assurez-vous de cocher l'option)

entrez la description de l'image ici

Assurez-vous de cocher l'option

Option 2

Utiliser un bloc vérifié et lancez une exception de débordement pour gérer la situation. Un exemple d'extrait de code serait

        try
        {
            checked
            {
                int y = 1000000000;
                short x = (short)y;
            }
        }
        catch (OverflowException ex)
        {
            MessageBox.Show("Overflow");
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error");
        }

Espère que cela va vous aider... :)

9
répondu oshan2csd 2015-04-02 08:11:33

J'ai déjà ajouté un cmt, mais c'est peut-être intéressant pour certains d'entre vous:

Msdn nous dit:

Dépassement arithmétique entier soit lance une OverflowException ou rejette les bits les plus significatifs de le résultat

Mais

Dépassement arithmétique décimal toujours lance une OverflowException.

Aussi

Lorsque le débordement d'entier se produit, quoi dépend de l'exécution contexte, qui peut être vérifié ou unchecked. Dans un activée contexte, un OverflowException est levée. Dans un contexte décoché, le plus les bits significatifs du résultat sont jeté et l'exécution se poursuit. Ainsi, C# vous donne le choix de manipulation ou ignorer le débordement.

6
répondu Andreas Niedermair 2010-01-13 12:19:39

Par défaut, C# ne vérifie pas le débordement arithmétique sur les entiers. Vous pouvez changer cela avec le /checked option du compilateur ou en activant "Vérifier le débordement/sous-flux arithmétique" 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 la vérification qui a lieu dans un morceau de code, l'activer explicitement en utilisant checked serait une bonne idée.

int j = checked(i * 2);

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

Note que les opérations en virgule flottante ne jettent jamais un OverflowException, et les opérations décimales jettent toujours un OverflowException. Voir aussi opérateurs C # .

6
répondu Thorarin 2010-01-13 12:29:33