不一致的不同的价值类型之间的鸿沟被零行为鸿沟、不同、行为、类型

2023-09-02 21:26:04 作者:痊愈与疤

请考虑以下code和评论:

Please consider the following code and comments:

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在运行,但是:

I can understand the compiler actively checking for division by zero constant and the DivideByZeroException at runtime but:

为什么要使用双在分频的零收益无限而不是抛出一个异常?这是设计或者是一个错误?

Why would using a double in a divide-by-zero return Infinity rather than throwing an exception? Is this by design or is it a bug?

只是踢,我在VB.NET这样做还有,以更加一致的结果:

Just for kicks, I did this in VB.NET as well, with "more consistent" results:

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的反馈,我跑这导致无穷如下:

Based on kekekela's feedback I ran the following which resulted in infinity:

    Console.WriteLine(1 / 
    .0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001);

此测试似乎证实了这个想法和文字双 0.0 其实是一个非常,非常小的一部分,这将导致无穷......

This test seems to corroborate the idea and a literal double of 0.0 is actually a very, very tiny fraction which will result in Infinity...

推荐答案

在一言以蔽之:在类型定义为无穷大的值,而 INT 类型没有。所以在情况下,计算的结果是,你实际上可以EX preSS给定类型的,因为它是定义的值。在int 情况下的,对于没有无穷大值,因此没有办法返回准确的结果。因此例外。

In a nutshell: the double type defines a value for infinity while the int type doesn't. So in the double case, the result of the calculation is a value that you can actually express in the given type since it's defined. In the int case, there is no value for infinity and thus no way to return an accurate result. Hence the exception.

VB.NET的事情确实有点不同了。使用 / 运营商的浮点值整数除法自动产生。这是为了让开发人员编写,如前pression 1 / ,并将其评价为 0.5 ,其中有些会考虑直观。如果你想看到的行为与C#一致的,试试这个:

VB.NET does things a little bit differently; integer division automatically results in a floating point value using the / operator. This is to allow developers to write, e.g., the expression 1 / 2, and have it evaluate to 0.5, which some would consider intuitive. If you want to see behavior consistent with C#, try this:

Console.WriteLine(1  0)

注意使用整数除法运营商( ,不是 / )以上。我相信你会得到一个异常。(或编译错误 - 不知道这)

Note the use of the integer division operator (, not /) above. I believe you'll get an exception (or a compile error--not sure which).

同样,试试这个:

Dim x As Object = 1 / 0
Console.WriteLine(x.GetType())

以上code将输出 System.Double

至于有关IM precision点,这里是看它的另一种方式。这并不是说在类型都有精确为零(它)没有价值;相反,类型并不意味着提供在首位的数学精确的结果的。 (某些值可以重新presented完全没错,但计算的给出准确的没有承诺。)毕竟,的的数学的EX pression价值 1/0 没有定义(最后我选中)。但 1 / X 趋于无穷大当x趋近于零。所以从这个角度来看,如果我们不能再present最分​​数 N / M 的完全的反正是有意义的治疗 X / 0 情况下近似,并给予价值它的办法的 - 再次,无穷大的定义,至少

As for the point about imprecision, here's another way of looking at it. It isn't that the double type has no value for exactly zero (it does); rather, the double type is not meant to provide mathematically exact results in the first place. (Certain values can be represented exactly, yes. But calculations give no promise of accuracy.) After all, the value of the mathematical expression 1 / 0 is not defined (last I checked). But 1 / x approaches infinity as x approaches zero. So from this perspective if we cannot represent most fractions n / m exactly anyway, it makes sense to treat the x / 0 case as approximate and give the value it approaches--again, infinity is defined, at least.