除以2乘以0.5乘以

时间:2014-04-06 11:08:49

标签: c#

请考虑以下事项:

void Foo(int start, int end)
{
    int mid = (start + end) / 2;
}

void Bar(int start, int end)
{
    int mid = (start + end) * 0.5;
}

为什么Foo成功编译而Bar没有?除以2隐式地将结果转换为int,而乘以0.5会得到未投放的double

  

无法将type' double隐式转换为int。显式转换   存在(你是否错过演员表?)

什么是C#语言设计师'这背后的推理?

4 个答案:

答案 0 :(得分:10)

/执行整数除法(5/3 = 1)。要使它执行浮点除法,其中一个操作数必须是浮点(floatdouble)。这是因为有些情况下您的应用程序想要访问商或部门的其余部分(对于您使用的余数%)。此外,整数除法比浮动除法更快。

另一方面,乘以浮点数总会返回一个浮点数。要将其保存为整数类型,您必须自己进行类型转换。浮点值在内存中具有不同的表示形式,也可能导致精度损失。

几乎所有的编程语言都是一样的:几乎所有编程语言都有整数除法和浮点除法,更常用的是同一个算子。几乎所有类型语言都需要从浮点到整数类型的转换。

答案 1 :(得分:5)

答案在C#文档中。在/ operator,它说

  

分割两个整数时,结果始终为整数。例如,7/3的结果是2。

乘法运算符没有这种行为,因此乘以double会产生一个double(整数可以在乘法之前隐式转换,因为它是一个加宽类型转换)。结果不能隐式转换,因为它将是一个缩小的类型转换。

答案 2 :(得分:4)

此问题与integer division无关。

这个问题就是为什么我可以做int / 2而我无法做int * 0.5

来自7.7.2 Division operator

int operator /(int x, int y);

这就是为什么可以做到的。

来自7.7.1 Multiplication operator

没有double * int,反之亦然,只有double * doubleint * int。由于没有从doubleint的隐式转换,但存在从intdouble的隐式转换,int将转换为{{1} }}。这就是编译器实际做的事情。

答案 3 :(得分:2)

知道了。

Foo()有效,因为操作中涉及的所有内容都是int数据类型。

因此,编译器在进行计算时没有问题,因为所有类型都是int类型,而mid也是int类型。所以编译器没有问题。

为了证明我的观点,如果你这样做,同样的Foo()将不起作用:

void Foo(int start, int end)
{
    int mid = (start + end) / 2.0;
}

因为,现在2.0是双倍的,并且计算在int + int / double之间,并且无法保证计算中的返回数字为{{ 1}}。

int正在进行整数除法,而Foo()正在进行浮点乘法