I would like to see the piece of code that does a floating-point division and returns Infinity
when dividing by zero. Where can I find it?
The motivation of wanting to know that comes from this code taken from the .NET documentation. I would have expected to get a DivideByZeroException
but instead I get Infinity
.
using System;
public class Example
{
public static void Main()
{
int number1 = 3000;
int number2 = 0;
Console.WriteLine((double)number1 / number2);
}
}
// The example displays the following output:
// Infinity
I found the documentation stating that floating-point division by zero does not throw an exception, so that's fine:
Dividing a floating-point value by zero doesn't throw an exception; it results in positive infinity, negative infinity, or not a number (NaN), according to the rules of IEEE 754 arithmetic. Because the following example uses floating-point division rather than integer division, the operation does not throw a DivideByZeroException exception.
In Visual Studio, I hovered over the "/" division sign and Resharper shows
double double.operator /(double left, double right)
And now, I'd like to see the implementation of that to see how that Infinity
is returned. But I can't find it.
I checked here
but don't see the division operator.
The above link then lead me here
but also nothing about the implementation detail.
I also looked here
but only see commented out code
/// Double IArithmetic<Double>.Divide(Double divisor, out bool overflowed) {
/// Double s = m_value / divisor;
/// overflowed = IsInfinity(s) || IsNaN(s);
/// return s;
/// }
Also nothing in the Double
implementation of corefx :
I would have expected something liked this (pseudo code):
public static double operator /(double left, double right)
{
if (right == 0)
{
return double.Infinity;
}
else
{
...
}
}
Your code compiles down to the following CIL:
.method public hidebysig static void Main() cil managed
{
.entrypoint
// Code size 21 (0x15)
.maxstack 2
.locals init (int32 V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldc.i4 0xbb8
IL_0006: stloc.0
IL_0007: ldc.i4.0
IL_0008: stloc.1
IL_0009: ldloc.0
IL_000a: conv.r8
IL_000b: ldloc.1
IL_000c: conv.r8
IL_000d: div
IL_000e: call void [mscorlib]System.Console::WriteLine(float64)
IL_0013: nop
IL_0014: ret
} // end of method Example::Main
That IL_000d: div
call is the divide operation happening. This means the CLR will perform the work, so you won't find any source code doing the work. If we dig into the CLR source code (here showing the coreclr) for the divide operator for floating point values:
TFp FpDiv(TFp dividend, TFp divisor)
{
#ifdef _TARGET_ARMARCH_
// From the ECMA standard:
//
// If [dividend] is zero and [divisor] is zero
// the result is NaN.
// If [dividend] is infinity and [divisor] is infinity
// the result is NaN.
if (dividend == 0 && divisor == 0)
{
return TFpTraits::NaN();
}
else if (!_finite(dividend) && !_isnan(dividend) && !_finite(divisor) && !_isnan(divisor))
{
return TFpTraits::NaN();
}
#endif // _TARGET_ARMARCH_
return dividend / divisor;
}
You can see it's handling some preconditions, then calling into the compiler's intrinsic operation. On x86 that will in turn be a FDIV
call, which is documented as raising a divide by zero flag, which the C runtime, thanks to IEEE 754, will turn into an infinity. This infinity works it way back up the chain to your C# app.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.