为什么整数除法在C#中返回一个整数,而不是一个浮点数?
有谁知道为什么在C#中的整数除法返回一个整数,但不是浮动? 背后有什么想法(它只是C / C ++的遗产)?
在C#中:
float x = 13 / 4; //imagine I used have overridden == operator here to use epsilon compare if (x == 3.0) print 'Hello world';
这个代码的结果是:
'Hello world'
严格地说,不存在整数除法(按定义划分是产生有理数的运算,整数是其中非常小的一个子集)。
新程序员在实际使用浮点除法的时候出现这种执行整数除法的错误是很常见的,但实际上整数除法是非常普通的操作。 如果你认为人们很less使用它,而且每次你进行分工,你总是需要记住投到浮点,你错了。
首先,整数除法比较快,所以如果你只需要一个整数的结果,人们会想要使用更高效的algorithm。
其次,有许多algorithm使用整数除法,如果除法结果总是浮点数,则每次都会被迫对结果进行舍入。 我头顶的一个例子就是改变一个数字的基数。 计算每个数字涉及数字的整数除以余数,而不是数字的浮点除法。
由于这些(和其他相关的)原因,整数除法结果是一个整数。 如果你想获得两个整数的浮点除法,你只需要记住把一个float
转换成double
/ float
/ decimal
。
请参阅C# 规范 。 有三种types的分工操作员
- 整数划分
- 浮点分割
- 十进制除法
在你的情况下,我们有整数除法,应用以下规则:
除法将结果舍入为零,结果的绝对值是可能的最大整数,小于两个操作数的商的绝对值。 当两个操作数具有相同的符号时,结果为零或正值,当两个操作数具有相反的符号时,结果为负值或负值。
我想为什么C#使用这种types的整数除法(有些语言返回浮动结果)是硬件 – 整数除法更快,更简单。
每种数据types都可以使每个运营商都负担过重。 如果分子和分母都是整数,则整数types将执行除法运算,并返回整数types。 如果你想要浮点除法,你必须先将一个或多个数字转换为浮点types,然后再进行分割。 例如:
int x = 13; int y = 4; float x = (float)y / (float)z;
或者,如果您使用文字:
float x = 13f / 4f;
请记住,浮点不精确。 如果你关心精度,可以使用类似十进制types的东西。
由于您不使用任何后缀,文字13
和4
被解释为整数:
手册 :
如果文字没有后缀,那么它的第一个types的值可以表示为:
int
,uint
,long
,ulong
。
因此,由于您声明13
为整数,所以将执行整数除法:
手册 :
对于x / yforms的操作,应用二元运算符重载parsing来select特定的运算符实现。 操作数被转换为所选操作符的参数types,结果的types是操作符的返回types。
下面列出了预定义的分区运算符。 运算符都计算x和y的商。
整数除法:
int operator /(int x, int y); uint operator /(uint x, uint y); long operator /(long x, long y); ulong operator /(ulong x, ulong y);
这样发生:
除法将结果舍入为零,结果的绝对值是可能的最大整数,小于两个操作数的商的绝对值。 当两个操作数具有相同的符号时,结果为零或正值,当两个操作数具有相反的符号时,结果为负值或负值。
如果您执行以下操作:
int x = 13f / 4f;
由于浮点除法( 13f
的/
运算符)会生成一个浮点数,所以您将收到一个编译器错误,该浮点数不能隐式转换为int。
如果你想让这个分部成为一个浮点部分,那么你必须使结果浮动:
float x = 13 / 4;
请注意,您仍将划分整数,这将隐式地转换为浮点数:结果将为3.0
。 要使用f
后缀( 13f
, 4f
)显式声明操作数为float。
它只是一个基本的操作 。
记住,当你学会分裂。 一开始我们9/6 = 1 with remainder 3
解了9/6 = 1 with remainder 3
。
9 / 6 == 1 //true 9 % 6 == 3 // true
/ -operator与%-operator结合使用来检索这些值。
可能有用:
double a = 5.0/2.0; Console.WriteLine (a); // 2.5 double b = 5/2; Console.WriteLine (b); // 2 int c = 5/2; Console.WriteLine (c); // 2 double d = 5f/2f; Console.WriteLine (d); // 2.5
如果你想要一个浮点结果,你将不得不将结果声明为floattypes,并将分子或分母转换为浮点数。
结果总是具有分子和分母的较大范围的types。 exception是byte和short,它们产生int(Int32)。
var a = (byte)5 / (byte)2; // 2 (Int32) var b = (short)5 / (byte)2; // 2 (Int32) var c = 5 / 2; // 2 (Int32) var d = 5 / 2U; // 2 (UInt32) var e = 5L / 2U; // 2 (Int64) var f = 5L / 2UL; // 2 (UInt64) var g = 5F / 2UL; // 2.5 (Single/float) var h = 5F / 2D; // 2.5 (Double) var i = 5.0 / 2F; // 2.5 (Double) var j = 5M / 2; // 2.5 (Decimal) var k = 5M / 2F; // Not allowed
在浮点types和小数types之间没有隐式转换,所以它们之间的分割是不允许的。 你必须明确地投射和决定你想要哪一个(十进制比浮点types有更高的精度和更小的范围)。