C# 除以2 vs乘以0.5
考虑以下几点:C# 除以2 vs乘以0.5,c#,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”隐式转换为int。需要显式转换 存在(您是否缺少演员阵容?) 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”隐式转换为int。需要显式转换
存在(您是否缺少演员阵容?)
C语言设计者在这背后的推理是什么?/
进行整数除法(5/3=1
)。要进行浮点除法,操作数之一必须是浮点(float
或double
)。这是因为在某些情况下,应用程序希望访问商或除法的余数(余数使用%
)。此外,整数除法比浮点除法快
另一方面,乘以一个浮点数总是返回一个浮点数。要将其保存为整数类型,您必须自己执行类型转换。浮点值在内存中有不同的表示形式,也可能导致精度损失
在几乎所有的编程语言中都是一样的:几乎所有的编程语言都有整数除法和浮点除法,通常使用相同的运算符。几乎所有类型化语言都需要从浮点类型转换为整数类型。答案在C#文档中。上面写着
当你除以两个整数时,结果总是一个整数。例如,7/3的结果是2
乘法运算符没有这种行为,所以乘以double会生成double(整数可以在被乘法之前隐式转换,因为它是一种类型转换)。结果不能隐式强制转换,因为这将是一个缩小的类型转换。此问题与
这个问题是关于为什么我可以做int/2
,但我不能做int*0.5
从
这就是为什么这样做是可以的
从
没有double*int
,反之亦然,只有double*double
和int*int
。由于不存在从double
到int
的隐式转换,而是存在从int
到double
的隐式转换,int
将转换为decimal
。这就是编译器的实际功能。明白了
Foo()
之所以有效,是因为操作中涉及的所有内容都是int
数据类型
因此,编译器在进行计算时不会有问题,因为所有的类型都是int
类型,而mid
也是int
类型。因此编译器不会有问题
为了证明我的观点,如果您这样做,相同的Foo()
将不起作用:
void Foo(int start, int end)
{
int mid = (start + end) / 2.0;
}
因为现在2.0
是双精度的,计算介于int
+int
/double
之间,并且不能保证计算返回的数字是int
Foo()
在做整数除法,而Bar()
在做浮点乘法我想你忘了提一下,为什么会这样。@RandRandom:稍微扩展一下。如果这不是你的意思,请在评论中更加明确。“这在所有编程语言中都是一样的。”我认为这句话太笼统了。谢谢,我已经扩展了它。如果有人想知道什么是非类型语言,一个例子就是TCL where。我想你忘了提到,为什么会有这种行为?我不知道你的意思。因为C#designers是这样创建的?但这背后的原因可能是什么,为什么这两个操作符的行为会不同,OP会特别问为什么他需要为其中一个而不是另一个进行转换。int+int=int
但是float+int=float
。如果执行float+int=int
操作,则会出现错误。就这么简单@斯蒂恩·梅。我想我放屁了。不管我说什么。
void Foo(int start, int end)
{
int mid = (start + end) / 2.0;
}