Il modo migliore per gestire l’overflow integer in C #?

Gestire l’overflow dei numeri interi è un’attività comune, ma qual è il modo migliore per gestirli in C #? C’è dello zucchero sintattico per renderlo più semplice rispetto ad altre lingue? O è davvero il modo migliore?

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

Non ho avuto bisogno di usarlo spesso, ma puoi usare la parola chiave spuntata :

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

Risulterà in un’eccezione di runtime in caso di overflow. Da MSDN:

In un contesto controllato, se un’espressione produce un valore che si trova al di fuori dell’intervallo del tipo di destinazione, il risultato dipende dal fatto che l’espressione sia costante o non costante. Le espressioni costanti causano errori in fase di compilazione, mentre le espressioni non costanti vengono valutate in fase di esecuzione e generano eccezioni.

Dovrei anche sottolineare che c’è un’altra parola chiave C #, unchecked , che ovviamente fa l’opposto di checked e ignora gli overflow. Potresti chiederti quando useresti mai un unchecked non unchecked poiché sembra essere il comportamento predefinito. Bene, c’è un’opzione del compilatore C # che definisce come vengono gestite le espressioni al di fuori di checked e unchecked : / checked . Puoi impostarlo nelle impostazioni di generazione avanzate del tuo progetto.

Se hai molte espressioni che devono essere controllate, la cosa più semplice da fare sarebbe in realtà impostare l’ /checked build /checked . Quindi qualsiasi espressione che trabocca, a meno che non sia racchiusa tra unchecked , genera un’eccezione di runtime.

Prova quanto segue

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

Il modo migliore è come Micheal Said: utilizzare la parola chiave Checked. Questo può essere fatto come:

 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()); } 

A volte, il modo più semplice è il modo migliore . Non riesco a pensare a un modo migliore per scrivere ciò che hai scritto, ma puoi limitarlo a:

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

Nota che non ho rimosso la variabile x perché sarebbe sciocco chiamare il foo() tre volte.

Vecchio thread, ma mi sono imbattuto in questo. Non volevo usare le eccezioni. Quello che ho finito è stato:

 long a = (long)b * (long)c; if(a>int.MaxValue || a 

Quindi, mi sono imbattuto in questo lontano dopo il fatto, e per lo più ha risposto alla mia domanda, ma per il mio caso particolare (nel caso in cui qualcun altro ha gli stessi requisiti), volevo qualcosa che avrebbe traboccato il valore positivo di un int firmato solo stabilirsi su int.MaxValue :

 int x = int.MaxValue - 3; int someval = foo(); try { x += someval; } catch (OverflowException) { x = int.MaxValue; }