为什么C#中的整数除法返回整数而不是浮点数?

时间:2012-06-01 13:32:45

标签: c# division

有谁知道为什么C#中的整数除法返回整数而不是浮点数? 它背后的想法是什么? (这只是C / C ++的遗产吗?)

在C#中:

float x = 13 / 4;   
//imagine I used have an overridden == operator here to use epsilon compare
if (x == 3.0)
   print 'Hello world';

此代码的结果将是:

'Hello world'

严格来说,没有整数除法这样的东西(按定义划分是一个产生有理数的运算,整数是一个非常小的子集。)

8 个答案:

答案 0 :(得分:73)

虽然新程序员在实际意图使用浮点除法时犯这种执行整数除法的错误是很常见的,但在实际操作中,整数除法是一种非常常见的操作。如果你假设人们很少使用它,并且每次你进行除法你总是需要记住施放到浮点数,你就错了。

首先,整数除法要快得多,所以如果你只需要一个整数结果,就可以使用效率更高的算法。

其次,有许多算法使用整数除法,如果除法的结果总是浮点数,则每次都要强制舍入结果。我头顶的一个例子就是改变一个数字的基数。计算每个数字涉及数字的整数除以及余数,而不是数字的浮点除法。

由于这些(及其他相关)原因,整数除法产生整数。如果你想得到两个整数的浮点除法,你只需要记住将一个转换为double / float / decimal

答案 1 :(得分:71)

请参阅C#specification。有三种类型的除法运算符

  • 整数分部
  • 浮点划分
  • 十进制分割

在您的情况下,我们有整数除法,并应用以下规则:

  

该除法将结果舍入为零,且绝对值为   结果是最大可能的整数小于   两个操作数的商的绝对值。结果为零   当两个操作数具有相同的符号且为0或0时为正   当两个操作数具有相反的符号时为负。

我认为C#使用这种整数除法(某些语言返回浮动结果)的原因是硬件 - 整数除法更快更简单。

答案 2 :(得分:32)

每种数据类型都能够使每个运算符重载。如果分子和分母都是整数,则整数类型将执行除法运算,它将返回整数类型。如果需要浮点除法,则必须在划分它们之前将一个或多个数字转换为浮点类型。例如:

int x = 13;
int y = 4;
float x = (float)y / (float)z;

或者,如果您使用文字:

float x = 13f / 4f;

请记住,浮点不准确。如果您关心精度,请使用十进制类型。

答案 3 :(得分:10)

由于您不使用任何后缀,因此文字134将被解释为整数:

  

Manual

     

如果文字没有后缀,则它具有可以表示其值的第一种类型:intuintlongulong。< / p>

因此,由于您将13声明为整数,因此将执行整数除法:

  

Manual

     

对于x / y形式的操作,应用二元运算符重载决策来选择特定的运算符实现。操作数将转换为所选运算符的参数类型,结果的类型是运算符的返回类型。

     

下面列出了预定义的除法运算符。运算符都计算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;

您将收到编译器错误,因为浮点除法(/的{​​{1}}运算符)会导致浮点数,无法隐式转换为int。

如果你想将除法作为浮点除法,你必须使结果成为浮点数:

13f

请注意,您仍然会对整数进行除法,这将被隐式地转换为float:结果将为float x = 13 / 4; 。要使用3.0后缀(f13f)将操作数显式声明为float。

答案 4 :(得分:6)

它只是一个基本操作

记得你何时学会分裂。一开始我们解决了9/6 = 1 with remainder 3

9 / 6 == 1  //true
9 % 6 == 3 // true

/ -operator与%-operator结合使用来检索这些值。

答案 5 :(得分:3)

可能有用:

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

答案 6 :(得分:2)

结果将始终是具有更大范围的分子和分母的类型。例外是字节和短,产生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

浮点类型和十进制类型之间没有隐式转换,因此不允许在它们之间进行划分。你必须明确地转换并决定你想要哪一个(与浮点类型相比,Decimal具有更高的精度和更小的范围)。

答案 7 :(得分:-1)

作为一个小技巧,您可以使用 var 来了解所获得的内容,这样编译器会告诉您所期望的类型:

int a = 1;
int b = 2;
var result = a/b;

您的编译器会告诉您结果在此处为 int 类型。