请考虑以下代码和评论:
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但是:
为什么在“除零”中使用双精度返回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
的字面翻倍实际上是一个非常非常微小的部分,它将导致无限......
答案 0 :(得分:35)
简而言之:double
类型定义了无穷大的值,而int
类型则没有。因此,在double
情况下,计算结果是一个值,您可以在给定类型中实际表达,因为它已定义。在int
情况下,无穷大没有值,因此无法返回准确的结果。因此例外。
/
运算符自动生成浮点值。这是为了允许开发人员编写例如表达式1 / 2
,并将其评估为0.5
,有些人会认为这是直观的。如果你想看到与C#一致的行为,试试这个:
Console.WriteLine(1 \ 0)
请注意上面使用整数除法运算符(\
,而不是/
)。我相信你会得到一个异常(或编译错误 - 不确定是哪个)。
同样,试试这个:
Dim x As Object = 1 / 0
Console.WriteLine(x.GetType())
以上代码将输出System.Double
。
至于关于不精确的观点,这是另一种看待它的方式。并不是double
类型没有完全为零的值(它确实如此);相反,double
类型并不意味着首先提供数学上精确的结果。 (某些值可以准确表示,是的。但计算不能保证准确性。)毕竟,数学表达式1 / 0
的值未定义(最后我查了一下)。但是当{x接近零时,1 / x
接近无穷大。因此,从这个角度来看,如果我们无法完全代表大多数分数n / m
,那么将x / 0
案例视为近似并给出接近的值 - 再次,至少定义了无穷大。
答案 1 :(得分:7)
double是一个浮点数而不是一个精确的值,所以你真正从编译器的角度划分的是接近于零但不完全为零的东西。
答案 2 :(得分:2)
因为“数字”浮点不是那种。浮点运算:
(有关示例,请参阅http://www.cs.uiuc.edu/class/fa07/cs498mjg/notes/floating-point.pdf)
浮点是一个解决特定问题的构造,并且在它不应该的时候被全部使用。我认为它们非常糟糕,但这是主观的。
答案 3 :(得分:1)
这可能与IEEE标准浮点和双精度浮点数具有指定的“无穷大”值有关。 .NET只是暴露了硬件级别已经存在的东西。
请参阅kekekela的回答,为什么这在逻辑上是有道理的。
答案 4 :(得分:1)
这是设计原因,因为double
类型符合IEEE 754,即浮点运算的标准。查看Double.NegativeInfinity和Double.PositiveInfinity的文档。
此常量的值是将正数{或负数}除以零的结果。