共用方式為


一般數學

.NET 7 會將新的數學相關泛型介面引入基類連結庫。 這些介面的可用性表示您可以將泛型類型或方法的類型參數限制為類似數字的類型。 此外,C# 11 和更新版本可讓您定義 static virtual 介面成員。 由於運算子必須宣告為 static,因此這個新的 C# 功能可讓運算符在類似數位類型的新介面中宣告。

這些創新使您能夠以通用方式執行數學運算,換句話說,不需要知道您正在使用的具體類型。 例如,如果您想要撰寫一個將兩個數字相加的方法,先前,您必須為每個類型新增多載的方法(例如 static int Add(int first, int second)static float Add(float first, float second))。 現在您可以撰寫單一泛型方法,其中 type 參數限制為類似數位的類型。 例如:

static T Add<T>(T left, T right)
    where T : INumber<T>
{
    return left + right;
}

在此方法中,類型參數 T 受限於實作新 INumber<TSelf> 介面的類型。 INumber<TSelf> 實作了 IAdditionOperators<TSelf,TOther,TResult> 介面,其中包含 + 運算子。 這可讓方法通用地加總兩個數字。 方法可以搭配任何 .NET 的內建數值類型使用,因為它們都已更新為在 .NET 7 中實作 INumber<TSelf>

函式庫作者將受益於泛型數學介面,因為他們可以藉由移除「冗餘」多載來簡化其程式碼基礎。 其他開發人員會間接受益,因為他們取用的 API 可能會開始支援更多類型。

介面

這些介面的設計既精細到足以讓用戶基於它們定義自己的接口,同時也具備細粒度以便於使用。 就該程度而言,有一些核心數值介面,大部分的用戶都會與其互動,例如 INumber<TSelf>IBinaryInteger<TSelf>。 更精細的介面,例如 IAdditionOperators<TSelf,TOther,TResult>ITrigonometricFunctions<TSelf>,支持這些類型,並可供定義自己的領域特定數值介面的開發人員使用。

數值介面

本節描述 中的 System.Numerics 介面,描述類似數字的類型及其可用的功能。

介面名稱 說明
IBinaryFloatingPointIeee754<TSelf> 公開實作 IEEE 754 標準的 二進位 浮點類型1 通用 API。
IBinaryInteger<TSelf> 公開二進位整數2通用的 API。
IBinaryNumber<TSelf> 公開二進位數通用的 API。
IFloatingPoint<TSelf> 公開浮點類型通用的 API。
IFloatingPointIeee754<TSelf> 公開實作 IEEE 754 標準的浮點類型通用 API。
INumber<TSelf> 公開與可比較數位類型通用的 API(實際上為「實際」數位網域)。
INumberBase<TSelf> 公開所有數字類型通用的 API(實際上為「複數」數位域)。
ISignedNumber<TSelf> 公開所有有號數字類型的共通 API(例如 NegativeOne 的概念)。
IUnsignedNumber<TSelf> 公開所有未帶正負號數字類型的通用 API。
IAdditiveIdentity<TSelf,TResult> 揭示(x + T.AdditiveIdentity) == x的概念。
IMinMaxValue<TSelf> 揭示T.MinValueT.MaxValue的概念。
IMultiplicativeIdentity<TSelf,TResult> 揭示(x * T.MultiplicativeIdentity) == x的概念。

1二進位 浮點類型Doubledouble)、 HalfSinglefloat)。

2 二進位 整數類型Bytebyte)、Int16short)、Int32int)、Int64long)、Int128IntPtrnint)、SBytesbyte)、UInt16ushort)、UInt32uint)、UInt64ulong)、UInt128UIntPtrnuint)。

您最有可能直接使用的介面是 INumber<TSelf>,大致對應到 數。 如果類型實作這個介面,則表示值具有正負號(這包含 unsigned 視為正數的類型),而且可以與相同類型的其他值進行比較。 INumberBase<TSelf> 更進階的概念,例如 數和 數,例如負數的平方根等。 已建立其他介面,例如 IFloatingPointIeee754<TSelf>,因為並非所有操作對所有數字類型都有意義。例如,計算數字的取整只對浮點數類型有意義。 在 .NET 基類連結庫中,浮點類型 DoubleIFloatingPointIeee754<TSelf> 實作,但 Int32 不會實作。

數個介面也由各種其他類型實作,包括 Char、、DateOnly、、DateTimeDateTimeOffsetDecimalGuidTimeOnlyTimeSpan

下表顯示每個介面所公開的一些核心 API。

介面 API 名稱 說明
IBinaryInteger<TSelf> DivRem 同時計算商數和餘數。
LeadingZeroCount 計算二進位表示法中前置零位的數目。
PopCount 計算二進位表示法中的設定位數目。
RotateLeft 向左旋轉位,有時也稱為圓形左移位。
RotateRight 向右旋轉位元,有時也稱為圓形右移位。
TrailingZeroCount 計算二進位表示法中尾端零位的數目。
IFloatingPoint<TSelf> Ceiling 將值四捨五入為正無限大。 +4.5 會變成 +5,而 -4.5 會變成 -4。
Floor 將值向下取整為負無限大。 +4.5 會變成 +4,而 -4.5 會變成 -5。
Round 使用指定的四捨五入模式將值進行四捨五入。
Truncate 把值向零取整。 +4.5 會變成 +4,而 -4.5 會變成 -4。
IFloatingPointIeee754<TSelf> E 取得表示類型的歐拉數的值。
Epsilon 取得對於某種類型來說大於零的最小可表示值。
NaN 取得值,表示 NaN 型別。
NegativeInfinity 取得值,表示 -Infinity 型別。
NegativeZero 取得值,表示 -Zero 型別。
Pi 取得值,表示 Pi 型別。
PositiveInfinity 取得值,表示 +Infinity 型別。
Tau 取得表示型別 Tau 的值(2 * Pi)。
(其他) (實作函數 介面下所列的完整介面集。
INumber<TSelf> Clamp 將值限制為不超過指定的最小值和最大值。
CopySign 將指定值的符號設為與另一個指定值相同。
Max 傳回兩個值中的較大值,如果其中一個輸入為 NaN,則傳NaN回 。
MaxNumber 傳回兩個值中的較大值,如果一個輸入為 NaN,則傳回數位。
Min 傳回兩個值的較小值,如果其中一個輸入為 NaN,則傳NaN回 。
MinNumber 傳回兩個值的較小值,如果一個輸入為 NaN,則傳回數位。
Sign 針對負值傳回 -1,0 表示零,而正值則傳回 +1。
INumberBase<TSelf> One 取得型別的值 1。
Radix 取得型別的進位或基底。 Int32 會傳回 2。 Decimal 返回 10。
Zero 取得型別的值 0。
CreateChecked 建立一個值,如果輸入無法容納,則會拋出OverflowException 。1
CreateSaturating 若輸入無法容納,則創建一個值,並將其限制在T.MinValueT.MaxValue之間。1
CreateTruncating 從另一個值建立一個新值,如果輸入無法容納,則會循環回到開始的值。1
IsComplexNumber 如果值具有非零實數部分和非零虛數部分,則傳回 true。
IsEvenInteger 如果值是偶數整數,則傳回 true。 2.0 會傳 true回 ,而 2.2 會傳 false回 。
IsFinite 如果值不是無限且不是 NaN,則傳回 true。
IsImaginaryNumber 如果值為零實數部分,則傳回 true。 這表示 0 是虛構的, 1 + 1i 不是。
IsInfinity 如果值代表無限大,則傳回 true。
IsInteger 如果值為整數,則傳回 true。 2.0 和 3.0 會傳回 true,而 2.2 和 3.1 則傳回 false
IsNaN 如果值表示 NaN,則傳回 true。
IsNegative 如果值為負數,則傳回 true。 這包括 -0.0。
IsPositive 如果值為正數,則傳回 true。 這包括 0 和 +0.0。
IsRealNumber 如果值為零虛數部分,則傳回 true。 這表示 0 和所有INumber<T>類型一樣真實。
IsZero 如果值代表零,則傳回 true。 這包括 0、+0.0 和 -0.0。
MaxMagnitude 傳回具有較大絕對值的值,如果任一輸入為 NaN,則傳NaN回 。
MaxMagnitudeNumber 傳回具有較大絕對值的值,如果一個輸入為 NaN,則會傳回數位。
MinMagnitude 傳回具有較小絕對值的值,如果任一輸入為 NaN,則傳NaN回 。
MinMagnitudeNumber 傳回具有較小絕對值的值,如果一個輸入為 NaN,則會傳回數位。
ISignedNumber<TSelf> NegativeOne 取得型別的值 -1。

1若要協助瞭解這三 Create* 種方法的行為,請考慮下列範例。

當給定值過大時的範例:

  • byte.CreateChecked(384) 會拋出 OverflowException
  • byte.CreateSaturating(384) 會傳回 255,因為 384 大於 Byte.MaxValue (也就是 255)。
  • byte.CreateTruncating(384) 會傳回 128,因為它會採用最低的 8 位(384 的十六進位表示, 0x0180而最低的 8 位為 0x80,也就是 128 位)。

當指定數值過小的範例:

  • byte.CreateChecked(-384) 會拋出 OverflowException
  • byte.CreateSaturating(-384) 會傳回 0,因為 -384 小於 Byte.MinValue (也就是 0)。
  • byte.CreateTruncating(-384) 會傳回 128,因為它會採用最低的 8 位(384 的十六進位表示, 0xFE80而最低的 8 位為 0x80,也就是 128 位)。

方法 Create* 也有 IEEE 754 浮點類型的特殊考慮,例如 floatdouble,因為它們具有特殊值 PositiveInfinityNegativeInfinityNaN。 這三個 Create* API 的行為如同 CreateSaturating。 此外,雖然 MinValueMaxValue 代表最大的負/正數「標準」數位,但實際的最小值和最大值為 NegativeInfinityPositiveInfinity,因此會改為固定這些值。

操作用戶介面

運算子介面對應於 C# 語言可用的各種運算子。

  • 它們不會明確配對運算,例如乘法和除法,因為這對所有類型都不正確。 例如, Matrix4x4 * Matrix4x4 有效,但 Matrix4x4 / Matrix4x4 無效。
  • 它們通常允許輸入和結果類型不同,以支援案例,例如分割兩個 double整數來取得 ,例如 , 3 / 2 = 1.5或計算一組整數的平均值。
介面名稱 已定義的運算子
IAdditionOperators<TSelf,TOther,TResult> x + y
IBitwiseOperators<TSelf,TOther,TResult> x & y、 'x |y'、、 x ^ y~x
IComparisonOperators<TSelf,TOther,TResult> x < yx > yx <= yx >= y
IDecrementOperators<TSelf> --xx--
IDivisionOperators<TSelf,TOther,TResult> x / y
IEqualityOperators<TSelf,TOther,TResult> x == yx != y
IIncrementOperators<TSelf> ++xx++
IModulusOperators<TSelf,TOther,TResult> x % y
IMultiplyOperators<TSelf,TOther,TResult> x * y
IShiftOperators<TSelf,TOther,TResult> x << yx >> y
ISubtractionOperators<TSelf,TOther,TResult> x - y
IUnaryNegationOperators<TSelf,TResult> -x
IUnaryPlusOperators<TSelf,TResult> +x

備註

有些介面除了定義一般未核取的運算子之外,還定義了已核取的運算子。 已檢查的運算子會在已檢查的上下文中呼叫,並允許使用者定義型別來定義溢位行為。 例如,如果您實作一個已檢查的運算子,如 CheckedSubtraction(TSelf, TOther),則您也必須實作一個未檢查的運算子,如 Subtraction(TSelf, TOther)

函式介面

函式介面會定義比特定 數值介面更廣泛地套用的常見數學 API。 這些介面都是由 IFloatingPointIeee754<TSelf>實作,而且未來可能會由其他相關類型實作。

介面名稱 說明
IExponentialFunctions<TSelf> 公開支援 e^xe^x - 12^x2^x - 110^x10^x - 1 的指數函式。
IHyperbolicFunctions<TSelf> 公開支援 acosh(x)asinh(x)atanh(x)cosh(x)sinh(x)tanh(x) 的雙曲函數。
ILogarithmicFunctions<TSelf> 公開支援 ln(x)、、 ln(x + 1)log2(x)log2(x + 1)log10(x)和 的 log10(x + 1)對數函式。
IPowerFunctions<TSelf> 公開支援的電源函式 x^y
IRootFunctions<TSelf> 公開支援cbrt(x)sqrt(x)的根函數。
ITrigonometricFunctions<TSelf> 公開支援 acos(x)、、 asin(x)atan(x)cos(x)sin(x)tan(x)的三角函數。

解析和格式化介面

剖析和格式化是程序設計的核心概念。 將使用者輸入轉換成指定類型或向用戶顯示類型時,通常會使用它們。 這些介面位於 命名空間中 System

介面名稱 說明
IParsable<TSelf> 提供T.Parse(string, IFormatProvider)T.TryParse(string, IFormatProvider, out TSelf)的支援。
ISpanParsable<TSelf> 提供T.Parse(ReadOnlySpan<char>, IFormatProvider)T.TryParse(ReadOnlySpan<char>, IFormatProvider, out TSelf)的支援。
IFormattable 1 公開的支援 value.ToString(string, IFormatProvider)
ISpanFormattable 1 公開的支援 value.TryFormat(Span<char>, out int, ReadOnlySpan<char>, IFormatProvider)

1這個介面不是新的,也不是泛型的。 不過,它由所有數字類型實作,並代表IParsable的反向運算。

例如,下列程式會採用兩個數位做為輸入,並使用泛型方法從主控台讀取數位,其中類型參數限制為 IParsable<TSelf>。 它會使用泛型方法計算平均值,其中輸入和結果值的型別參數限制為 INumber<TSelf>,然後將結果顯示給控制台。

using System.Globalization;
using System.Numerics;

static TResult Average<T, TResult>(T first, T second)
    where T : INumber<T>
    where TResult : INumber<TResult>
{
    return TResult.CreateChecked( (first + second) / T.CreateChecked(2) );
}

static T ParseInvariant<T>(string s)
    where T : IParsable<T>
{
    return T.Parse(s, CultureInfo.InvariantCulture);
}

Console.Write("First number: ");
var left = ParseInvariant<float>(Console.ReadLine());

Console.Write("Second number: ");
var right = ParseInvariant<float>(Console.ReadLine());

Console.WriteLine($"Result: {Average<float, float>(left, right)}");

/* This code displays output similar to:

First number: 5.0
Second number: 6
Result: 5.5
*/

另請參閱