请考虑以下代码和注释:
Console.WriteLine(1 / 0); // will not compile, error: Division by constant zero int i = 0; Console.WriteLine(1 / i); // compiles, runs, throws: DivideByZeroException double d = 0; Console.WriteLine(1 / d); // compiles, runs, results in: Infinity
我可以理解编译器在运行时主动检查除零常量和DivideByZeroException的情况,但是:
为什么要在被零除的整数中使用double返回Infinity而不是抛出异常?这是设计使然还是错误?
只是为了踢球,我也在VB.NET中做到了这一点,结果是“更加一致”:
dim d as double = 0.0 Console.WriteLine(1 / d) ' compiles, runs, results in: Infinity dim i as Integer = 0 Console.WriteLine(1 / i) ' compiles, runs, results in: Infinity Console.WriteLine(1 / 0) ' compiles, runs, results in: Infinity
编辑:
根据kekekela的反馈,我执行了以下操作,导致无穷大:
Console.WriteLine(1 / .0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001);
这个测试似乎证实了这个想法,字面值的两倍0.0实际上是非常非常小的分数,这将导致Infinity …
0.0
简而言之:double类型定义了无穷大的值,而类型定义了无穷大int。因此,在这种double情况下,由于定义了计算结果,因此实际上是可以在给定类型中表示的值。在这种int情况下,没有无穷大值,因此没有办法返回准确的结果。因此,例外。
double
int
VB.NET所做的事情有些不同。整数除法使用/运算符自动产生浮点值。这是为了使开发人员可以编写表达式1 / 2,并将其求值为0.5,有些人会认为这很直观。如果要查看与C#一致的行为,请尝试以下操作:
/
1 / 2
0.5
Console.WriteLine(1 \ 0)
请注意,上面使用了 整数除法 运算符(\,not /)。我相信您会得到一个异常(或编译错误-不确定哪个)。
\
同样,请尝试以下操作:
Dim x As Object = 1 / 0 Console.WriteLine(x.GetType())
上面的代码将输出System.Double。
System.Double
至于不精确点,这是另一种看待它的方法。并不是说double类型没有正好为零的值(而是)。相反,该double类型并不意味着首先提供 数学上精确的结果 。(可以准确地表示某些值,是的。但是 计算 不能保证准确性。)毕竟,没有定义 数学 表达式的值1 / 0(我最后检查过)。但是1 / x随着x接近零,接近无穷大。因此,从这个角度来看,如果我们仍然无法n / m 精确地 表示大部分分数,则将x / 0案例视为近似值并给出其 接近 的值 __-再次,至少定义了无限。
1 / 0
1 / x
n / m
x / 0