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

Ban*_*nny 120 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';
Run Code Online (Sandbox Code Playgroud)

此代码的结果将是:

'Hello world'
Run Code Online (Sandbox Code Playgroud)

严格地说,没有整数除法这样的东西(按定义除法是产生有理数的运算,整数是其中一小部分.)

Ser*_*rvy 85

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

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

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

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

  • @pelesl因为这将是一个巨大的*突破性的变化来做一个天文数字的程序将被打破我可以完全相信它将永远不会发生在C#.这是从第1天开始用语言完成的事情或根本不需要完成的事情. (5认同)
  • 在VB.Net .Net架构师做出了另一个决定:/ - 总是一个浮点除法,\ - 整数除法,所以它有点不一致,除非你考虑C++遗留; (4认同)
  • 您可以在编译时确定`/`运算符是执行整数除法还是浮点除法(除非您使用动态).如果由于你在那一行上做了很多事情而难以弄明白,那么我建议将该行分成几行,以便更容易弄清楚操作数是整数还是浮点数类型.您的代码的未来读者可能会欣赏它. (4认同)
  • 我个人觉得有问题的是我总是要考虑我正在划分的变量,我认为这是浪费我的注意力. (4认同)
  • @Servy:在 C、C++ 和 C# 中有很多类似的东西。就我个人而言,我认为 C# 会是一种更好的语言,如果有一个不同的整数除法运算符,并且为了避免合法的代码产生令人惊讶的行为,`int/int` 运算符就是非法的 [诊断指定代码必须强制转换操作数或使用其他运算符,具体取决于所需的行为]。是否有其他一些好的标记序列可用于整数除法,为此目的可能会弃用`/`,但我不知道什么是实用的。 (2认同)
  • MSBasic 总是有 \ 和 /,早在 .NET 出现之前。并且请不要说我们想要像 Python 一样多的重大更改。几乎每个 Python 项目都需要特定版本才能工作。这是一场噩梦。 (2认同)

Ser*_*kiy 75

请参阅C#规范.有三种类型的除法运算符

  • 整数除法
  • 浮点除法
  • 十进制除法

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

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

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

  • 正如@SHINJaeGuk所说,Delphi默认除法运算符/返回浮动结果。另外,Delphi 有一个特殊的除法运算符“div”,它返回整数结果:“5 / 2 = 2.5”“5 div 2 = 2” (3认同)

Ste*_*art 36

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

int x = 13;
int y = 4;
float x = (float)y / (float)z;
Run Code Online (Sandbox Code Playgroud)

或者,如果您使用文字:

float x = 13f / 4f;
Run Code Online (Sandbox Code Playgroud)

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

  • +1 提到只有一项需要浮点才能进行浮点除法。 (2认同)

Cod*_*ter 11

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

手册:

如果文字没有后缀,它具有第一这些类型的,其中它的值可以表示的:int,uint,long,ulong.

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

手册:

对于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);
Run Code Online (Sandbox Code Playgroud)

因此四舍五入发生:

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

如果您执行以下操作:

int x = 13f / 4f;
Run Code Online (Sandbox Code Playgroud)

您将收到编译器错误,因为浮点除法(/运算符13f)导致浮点数,无法隐式转换为int.

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

float x = 13 / 4;
Run Code Online (Sandbox Code Playgroud)

请注意,您仍将除以整数,它将隐式地转换为float:结果将是3.0.要使用f后缀(13f,4f)将操作数显式声明为float .

  • +1解释说你可以将答案作为浮点数但仍然进行整数除法。此外,我见过的强制浮点除法的另一种常见方法是将除法的第一项乘以“1.0”。 (2认同)

eoz*_*ten 10

可能有用:

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
Run Code Online (Sandbox Code Playgroud)


z m*_*z m 8

结果将始终是分子和分母范围更大的类型。例外是 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
Run Code Online (Sandbox Code Playgroud)

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


L. *_*nty 7

它只是一个基本的操作.

记得当你学会划分时.一开始我们解决了9/6 = 1 with remainder 3.

9 / 6 == 1  //true
9 % 6 == 3 // true
Run Code Online (Sandbox Code Playgroud)

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