2016-07-12 3 views
0

デバッグモードでは、このコードの2倍をintで割った結果、System.Overflow例外が発生します。 int32の値が小さすぎる/大きいです。オーバーフロー例外double into int

0.0d/0 is NaNの結果。明らかにintに収まりません。

int result = Convert.ToInt32(0.0d/0); 

しかし、このシナリオを正しく処理して例外が発生しないようにするにはどうすればよいですか?または私はそれをキャッチしようとする必要があります?

+5

本当の質問は次のとおりです。なぜゼロで割っていますか? –

+0

整数のオーバーフローはすべて、コンパイルオプションに依存します。 –

+1

単純な条件で簡単に修正する必要があります。divisorの値が0の場合は除算しないでください。 – Esko

答えて

1

あなたのアプリケーションの期待に完全に依存していると思います。

doubleがNaNまたはInt32.MaxValueより大きいとわかっていて、特定の結果を続ける関数が好きなら、小切手を書いてください。

実際の例外である特別なロジックによってスタックが処理される必要がある場合は、例外をスローする必要があります。

+0

"私はあなたのアプリケーションの期待に完全に依存していると思います。正しく、したがって、私のビジネスロジックは、0の値を0にテストし、0.0の変数を0に戻します。アイオープナーに感謝します! – Elisabeth

2

intのバイトサイズは、すべての可能なdoubleの値に適合するには小さすぎます。 Data Typesを参照してください。最適な選択肢は、tryブロック内で変換を実行し、OverflowExceptionをキャッチすることです。

try 
{ 
    int result = Convert.ToInt32(0.0d/0); 
} 
catch (OverflowException) 
{ 
    //...   
} 
0

あなたはすでに「NaNで」OKであり、そのような結果が発生したときにそのintに何を置くべきであるかどうかを決定することができるはずですので、この計算は、計算することになっているか知っています。あなたはそれをキャッチするかもしれません。それが起こらないように、ifを追加することができます。あなたはそれを残すことができる。必要なことは何でも行うことができますが、先にを決定する必要があります。0.0が発生したときに何をしたいのですか。それは何らかの理由でそこにあります。

を参照してください。0.0/0.0は、通常、コードにエラーを意味します。 0/0は決して意味をなさないので、Not-a-Numberはそれについて思い出させる結果です。

一般に、ゼロ除算が発生した理由をトレースして診断することができます。 2番目の変数がなぜゼロであるのか(なぜ/0.0で、なぜ/1.0ではないのか)を調べ、それが有効な値であるかどうかを判断し、そうでない場合にはそのコードを修正してゼロを発生させないまったく。例えば

、数式forcepower(x,z)/distance(x,z)を有し、xzが同じ点であったため、パワーと距離の両方がゼロであることが判明し、その後は、x == Zをチェックifを追加する結果を強制する可能性がある場合そのような場合には0.0とする。しかし、もしその式が次のように計算されれば、あなたは最も淡い数値を選ぶべきです。知りません。あなたがすべき。

---編集

あなたのご意見の後、私は今理解しています。だからあなたは分裂で使われているすべての価値を支配している - 良い!

すでに 'bar'をゼロにテストしているので、この場合は 'foo'をゼロにします(私はあなたのコメントを '何も計算できないため'と見ています)。結果を設計したか、または「コード化した」。

0.0または0に何かを強制することは、「何も計算されていません」ということを示す良い方法ではありません。コードの後半部分では、bazz0であるかどうかを判断するのは難しいでしょう。

確かに、もちろん、0は通常、その後、発生しないことができ、実際に無効な値がある場合はその時々 OK特別な「何もない」-indicating値としてそれを使用...

..butようにしますあなたはそれがinobvious問題を引き起こす可能性がありますし、「値が良好である」場合も、それはすべての場所でをチェックすることを忘れないようにあなたを強制的に、その0/0ケースから見た:

double foo; 
if(bar != 0) foo = calculate_the_foo(); // check the Bar maybe it's zero 
else foo = 0.0; // can't calculate, no foo 

double z; 
if(bar != 0) z = foo/bar; // added a check against zero in bar again.. 
else z = ...um? what to use here.. 0 again? 

int result = Convert.ToInt32(z); 

// later in the code 
if(result != 0) //..again? but.. is it result of 0 or no result? 
    .. 

// and so on 

それは、非常に簡単です忘れる 特別な値をチェックし、単にresult = foo/barと書いて、無限、NaN、またはオーバーフローを得る。

したがって、通常のゼロを意味し、失われたデータを表示するための適切な無価値なものを使用するために本当にに0を使用するずっと良い..です

は、最も簡単な1が昔ながらのある..and ... null

あなたがint?またはdouble?のようなnullablesを使用する場合は、あなたは、単にのようなもの書くことができます。

using System.IO; 
using System; 

class Program 
{ 
    static void Main() 
    { 
     double? foo = 5.0; 
     double? bar = 4.0; 
     double? result = foo/bar; 
     Console.WriteLine("x/y: " + prettynulls(result)); 
     // ^writes: 1.25 

     foo = null; 
     bar = 4.0; 
     result = foo/bar; 
     Console.WriteLine("null/y: " + prettynulls(result)); 
     // ^writes: (null) 

     foo = 5.0; 
     bar = null; 
     result = foo/bar; 
     Console.WriteLine("x/null: " + prettynulls(result)); 
     // ^writes: (null) 

     foo = null; 
     bar = null; 
     result = foo/bar; 
     Console.WriteLine("null/null: " + prettynulls(result)); 
     // ^writes: (null) 
    } 

    private static string prettynulls(double? val) 
    { 
     return val == null ? "(null)" : val.ToString(); 
    } 
} 

は、あなたも+のような操作を行うことができますことを確認してください - if秒のトンせずにそれらの上に/ *をチェックしますヌルの場合。数学演算は、1つのオペランドがnullの場合にnullを返します。したがって、あなたの場合はなる:

double? foo; 
if(...) foo = calculate_the_foo(); 
else foo = null; 

int? result = (int?)(foo/bar); 

のfooは計算できないnullablesとcalculateは、スマートすることによって:シンプルさと表現力で

double? foo = calculate_the_foo(); 

int? result = (int?)(foo/bar); 

ルック。 double?のようなNullablesもキャストを処理します。 nullを保持するdouble?は、int?にキャストされると、単にnullとなります。それ以外の場合は、double値をintにキャストしてintを返します。

+0

であり、0.0/0である。 。 。 – Elisabeth

+0

@エリザベス:何らかの理由でゼロになる 'foo/bar'変数ではありませんか?つまり、それは文字通り '0.0/0'としてハードコードされていますか?それは完全なナンセンスです。誰がそのコードを書いているのかを確認し、なぜ彼らがそれをしたのか尋ねる。たぶん彼らはそこを離れて、いつも "to - do"として投げた。 – quetzalcoatl

+0

ご迷惑をおかけして申し訳ありません。もちろんそのfoo/barでもデータは0.0(foo)と0(bar)ですが、barが0の場合はfooも0でなければならないので、barが0の場合はfooの場合0を返します.-) – Elisabeth

関連する問題