在调试模式下,这行代码双重除以int会导致System.Overflow异常。 int32的值太小/太大。
0.0d/0 is NaN
的结果。这显然不适合int。
int result = Convert.ToInt32(0.0d/0);
但是如何正确处理这种情况,没有异常发生?或者我应该尝试抓住它?
答案 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)
并且权力和距离都是零,因为x
和z
是相同的点,那么你可以添加一个if
检查x == z并在这种情况下强制结果为0.0。但是,如果该公式计算为foobarized whachamacallit,那么你应该选择最具弹性的数字。我不知道。你应该。
---修改
好的,在您发表评论后我现在明白了。所以你可以控制分裂中使用的所有值 - 好!
因为你已经测试'bar'为零,在这种情况下强制'foo'为零(我已经看到你的评论'因为没有什么可以计算然后')然后问题实际上是你的方式设计,或“编码”结果。
将某些内容强制为0.0
或0
并不是表示“没有计算任何内容”的好方法。在代码的后面部分,您将很难确定bazz
是0
是因为它是结果,还是因为它没有计算出来。
当然,如果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 );
calculate
智能与nullables:
double? foo = calculate_the_foo();
int? result = (int?)( foo/bar );
看看简洁和表现力。像double?
这样的无效句子甚至可以处理。保存double?
的{{1}}在投放到null
时只会返回int?
。否则,它会将double值转换为int并返回int。