C#做浮点除法的代码在哪里?
Where is the code that does floating-point division for C#?
问题
我想看看除以零时进行浮点除法和 returns Infinity
的代码段。我在哪里可以找到它?
代码示例
想知道的动机来自从 .NET 文档中获取的这段代码。我本来希望得到 DivideByZeroException
但我得到 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
文档
我发现文档说明浮点数除以零不会抛出异常,所以没关系:
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.
.NET Framework 中的代码
在 Visual Studio 中,我将鼠标悬停在“/”分隔符上,Resharper 显示
double double.operator /(double left, double right)
现在,我想看看它的实现,看看 Infinity
是如何返回的。但是我找不到。
我在这里查看了
但看不到除法运算符。
以上link那带我来
但也没有实现细节。
我也看过这里
但只能看到注释掉的代码
/// Double IArithmetic<Double>.Divide(Double divisor, out bool overflowed) {
/// Double s = m_value / divisor;
/// overflowed = IsInfinity(s) || IsNaN(s);
/// return s;
/// }
在 corefx 的 Double
实现中也没有任何内容:
我会期待这样的东西(伪代码):
public static double operator /(double left, double right)
{
if (right == 0)
{
return double.Infinity;
}
else
{
...
}
}
您的代码编译为以下 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
IL_000d: div
调用是除法运算。这意味着 CLR 将执行这项工作,因此您不会找到任何源代码来执行这项工作。如果我们深入研究浮点值除法运算符的 CLR 源代码(此处显示 coreclr):
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;
}
您可以看到它正在处理一些先决条件,然后调用编译器的内部操作。在 x86 上,这又是一个 FDIV
调用,它被记录为引发一个除以零标志,C 运行时,由于 IEEE 754,将变成一个无穷大。这个无穷大的工作方式将链备份到您的 C# 应用程序。
问题
我想看看除以零时进行浮点除法和 returns Infinity
的代码段。我在哪里可以找到它?
代码示例
想知道的动机来自从 .NET 文档中获取的这段代码。我本来希望得到 DivideByZeroException
但我得到 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
文档
我发现文档说明浮点数除以零不会抛出异常,所以没关系:
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.
.NET Framework 中的代码
在 Visual Studio 中,我将鼠标悬停在“/”分隔符上,Resharper 显示
double double.operator /(double left, double right)
现在,我想看看它的实现,看看 Infinity
是如何返回的。但是我找不到。
我在这里查看了
但看不到除法运算符。
以上link那带我来
但也没有实现细节。
我也看过这里
但只能看到注释掉的代码
/// Double IArithmetic<Double>.Divide(Double divisor, out bool overflowed) {
/// Double s = m_value / divisor;
/// overflowed = IsInfinity(s) || IsNaN(s);
/// return s;
/// }
在 corefx 的 Double
实现中也没有任何内容:
我会期待这样的东西(伪代码):
public static double operator /(double left, double right)
{
if (right == 0)
{
return double.Infinity;
}
else
{
...
}
}
您的代码编译为以下 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
IL_000d: div
调用是除法运算。这意味着 CLR 将执行这项工作,因此您不会找到任何源代码来执行这项工作。如果我们深入研究浮点值除法运算符的 CLR 源代码(此处显示 coreclr):
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;
}
您可以看到它正在处理一些先决条件,然后调用编译器的内部操作。在 x86 上,这又是一个 FDIV
调用,它被记录为引发一个除以零标志,C 运行时,由于 IEEE 754,将变成一个无穷大。这个无穷大的工作方式将链备份到您的 C# 应用程序。