溢出异常加倍为int

时间:2016-07-12 07:32:27

标签: c#

在调试模式下,这行代码双重除以int会导致System.Overflow异常。 int32的值太小/太大。

0.0d/0 is NaN的结果。这显然不适合int。

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

但是如何正确处理这种情况,没有异常发生?或者我应该尝试抓住它?

3 个答案:

答案 0 :(得分:2)

int的字节大小太小,无法容纳所有可能的double值。见Data Types。您最好的选择是在try-block中执行转换并捕获OverflowException

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

答案 1 :(得分:1)

我说这完全取决于您的应用程序预期。

如果您知道double可以是NaN或者只是大于Int32.MaxValue,并且您希望函数继续使用特定结果,那么您应该写一个支票。

如果溢出是一个需要通过某种特殊逻辑向上处理的实际异常,则应抛出异常。

答案 2 :(得分:0)

你知道这个计算应该计算什么,所以你应该已经能够确定'NaN'是否正常以及当发生这样的结果时应该将什么放入int。你可能会抓住它。您可以添加if以确保它不会发生。你可以离开它。你可以做任何你需要的事情,但首先,当0.0发生时,你需要决定你想要发生什么。它出于某种原因。

看到0.0/0.0通常意味着代码中的错误早期。 0/0几乎没有意义,因此Not-a-Number是提醒它的结果。

通常,您可能希望跟踪并诊断为什么会发生除零。检查为什么第二个变量为零(为什么是/0.0而不是/1.0?),判断它是否是一个有效的可能值,如果不是,那么修复负责该零的代码,这样零就不会发生一点都不。

例如,如果你有一个公式forcepower(x,z) / distance(x,z)并且权力和距离都是零,因为xz是相同的点,那么你可以添加一个if检查x == z并在这种情况下强制结果为0.0。但是,如果该公式计算为foobarized whachamacallit,那么你应该选择最具弹性的数字。我不知道。你应该。

---修改

好的,在您发表评论后我现在明白了。所以你可以控制分裂中使用的所有值 - 好!

因为你已经测试'bar'为零,在这种情况下强制'foo'为零(我已经看到你的评论'因为没有什么可以计算然后')然后问题实际上是你的方式设计,或“编码”结果。

将某些内容强制为0.00并不是表示“没有计算任何内容”的好方法。在代码的后面部分,您将很难确定bazz0是因为它是结果,还是因为它没有计算出来。

当然,如果0是一个通常永远不会发生的实际无效值,那么它的有时可以将它用作特殊的“无”指示值。

..但正如你从那个0/0案例中看到的那样,它可能会导致明显的问题,而且如果'价值很好',它还会强迫你记住在每个地方检查:< / p>

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表示正常零并使用正确的无值表示缺少数据好得多

..而最简单的就是陈旧...... null

如果您使用int?double?之类的无效符号,那么您可以简单地编写如下内容:

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 s的情况下对它们执行+ - / *等操作来检查空值。如果一个操作数为null,则数学运算将返回null。因此,您的案件将成为:

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

int? result = (int?)( foo/bar );
通过在无法计算foo时使calculate智能与nullables:

double? foo = calculate_the_foo();

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

看看简洁和表现力。像double?这样的无效句子甚至可以处理。保存double?的{​​{1}}在投放到null时只会返回int?。否则,它会将double值转换为int并返回int。