Because the C language was designed [essentially] as a hardware-agnostic assembly language. Consequently, division, unless it involves a floating point value is integer division, the a CPU will do it in a single instruction. That means that an expression like:
int x = 9 ;
int y = 5 ;
int z = x / y ;
That will usually compile down to a single machine instruction (possibly with others to load/store values to/from registers, the net result of which is a quotient and a remainder. So, the above int z = x / y
will resolve to 1
, leaving the remainder of 4
on the table (note that if you want the remainder, use the %
operator: int z = x % y
yields the expected 4
.
If one of the operands is a floating point value, then floating point division is used (much expensive, computationally speaking).
Since C# inherits from that legacy, it behaves in the same way. So, §14.7.2 of the Standard says
14.7.2 Division operator
For an operation of the form x / y
, binary operator overload resolution (§14.2.4) is applied
to select a specific operator implementation. The operands are converted to the parameter types
of the selected operator, and the type of the result is the return type of the operator.
The predefined division operators are listed below.
The operators all compute the quotient of x
and y
.
Integer division:
int operator /( int x, int y );
uint operator /( uint x, uint y );
long operator /( long x, long y );
ulong operator /( ulong x, ulong y );
void operator /( long x, ulong y );
void operator /( ulong x, long y );
The operators with void
return type always produce a compile-time error. Consequently,
it is an error for one operand to be of type long
and the other to be of type ulong
.
If the value of the right operand is zero, a System.DivideByZeroException
is thrown.
The division rounds the result towards zero, and the absolute value of the result is
the largest possible integer that is less than the absolute value of the quotient of
the two operands. The result is zero or positive when the two operands have the same
sign and zero or negative when the two operands have opposite signs.
If the left operand is the smallest int
or long
value (−231 or −263,
respectively) and the right operand is –1
, an overflow occurs. In a checked
context, this
causes a System.ArithmeticException
(or a subclass thereof) to be thrown. In an unchecked
context, it is implementation-defined as to whether a System.ArithmeticException
(or a
subclass thereof) is thrown or the overflow goes unreported with the resulting value being that
of the left operand.
[discussion of floating-point and decimal division elided]
That's why.