[英]Where is the code that does floating-point division for C#?
我想看看執行浮點除法並在除以零時返回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
我發現文檔說明浮點除以零不會引發異常,所以這很好:
將浮點值除以零不會引發異常; 根據 IEEE 754 算術規則,它會導致正無窮大、負無窮大或非數字 (NaN)。 由於以下示例使用浮點除法而不是 integer 除法,因此該操作不會引發 DivideByZeroException 異常。
在 Visual Studio 中,我將鼠標懸停在“/”除號上,Resharper 顯示
double double.operator /(double left, double right)
現在,我想看看它的實現,看看Infinity
是如何返回的。 但我找不到它。
我在這里檢查
但看不到除法運算符。
然后上面的鏈接將我帶到這里
但也沒有關於實現細節。
我也看過這里
但只看到注釋掉的代碼
/// 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
調用,這被記錄為引發除以零標志,由於 IEEE 754,C 運行時將變成無窮大。 這種無窮大的工作方式將鏈備份到您的 C# 應用程序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.