web-dev-qa-db-fra.com

Le meilleur moyen de gérer le débordement d’entiers en C #?

La gestion du dépassement d'entier est une tâche courante, mais quel est le meilleur moyen de le gérer en C #? Y at-il un sucre syntaxique pour le rendre plus simple qu'avec d’autres langues? Ou est-ce vraiment le meilleur moyen?

int x = foo();
int test = x * common;
if(test / common != x)
    Console.WriteLine("oh noes!");
else
    Console.WriteLine("safe!");
38
Ben Lakey

Je n'ai pas eu besoin de l'utiliser souvent, mais vous pouvez utiliser le mot-clé vérifié :

int x = foo();
int test = checked(x * common);

Entraînera une exception d'exécution en cas de débordement. De MSDN:

Dans un contexte coché, si une expression produit une valeur qui est en dehors de la plage du type de destination, le résultat dépend de si l'expression est constante ou non constante. Constant les expressions provoquent des erreurs de compilation, alors que les expressions non constantes sont évalués au moment de l'exécution et déclenchent des exceptions.

Je devrais également signaler qu’il existe un autre mot clé C #, unchecked, qui bien sûr fait l’opposé de checked et ignore les débordements. Vous pourriez vous demander quand vous utiliseriez jamais unchecked car il semble s'agir du comportement par défaut. Eh bien, il existe une option de compilateur C # qui définit comment les expressions autres que checked et unchecked sont traitées: /vérifié . Vous pouvez le définir dans les paramètres de construction avancés de votre projet.

Si vous avez besoin de vérifier un grand nombre d'expressions, la solution la plus simple consiste à définir l'option de génération /checked. Ensuite, toute expression qui déborde, sauf si elle est enveloppée dans unchecked, entraînera une exception d'exécution.

95
Michael Petito

Essayez ce qui suit

int x = foo();
try {
  int test = checked (x * common);
  Console.WriteLine("safe!");
} catch (OverflowException) {
  Console.WriteLine("oh noes!");
}
18
JaredPar

Comme le dit Micheal Said, utilisez le mot-clé Vérifié .

int x = int.MaxValue;
try   
{
    checked
    {
        int test = x * 2;
        Console.WriteLine("No Overflow!");
    }
}
catch (OverflowException ex)
{
   Console.WriteLine("Overflow Exception caught as: " + ex.ToString());
}
7
Chinjoo

Parfois, le plus simple moyen est le meilleur moyen. Je ne peux pas penser à un meilleur moyen d'écrire ce que vous avez écrit, mais vous pouvez le résumer comme suit:

int x = foo();

if ((x * common) / common != x)
    Console.WriteLine("oh noes!");
else
    Console.WriteLine("safe!");

Notez que je n’ai pas supprimé la variable x car il serait insensé d’appeler le foo() trois fois.

4
Alon Gubkin

Vieux fil, mais je viens de courir dans cela. Je ne voulais pas utiliser d'exceptions. Ce que j'ai fini par être:

long a = (long)b * (long)c;
if(a>int.MaxValue || a<int.MinValue)
    do whatever you want with the overflow
return((int)a);
1
YourUncleBob

Donc, je suis tombé sur cette affaire très longtemps après et la plupart du temps, cela répondait à ma question, mais pour mon cas particulier (si quelqu'un d'autre avait les mêmes exigences), je voulais quelque chose qui dépasserait la valeur positive d'un int signé en régler à int.MaxValue:

int x = int.MaxValue - 3;
int someval = foo();

try
{
   x += someval;
}

catch (OverflowException)
{
   x = int.MaxValue;
}
0
Jesse Williams