Genel matematik

.NET 7, temel sınıf kitaplığına matematikle ilgili yeni genel arabirimler sunar. Bu arabirimlerin kullanılabilirliği, genel bir tür veya yöntemin tür parametresini "sayı benzeri" olacak şekilde kısıtlayabileceğiniz anlamına gelir. Ayrıca, C# 11 ve üzeri arabirim üyeleri tanımlamanızı static virtual sağlar. İşleçlerin olarak staticbildirilmesi gerektiğinden, bu yeni C# özelliği işleçlerin sayı benzeri türler için yeni arabirimlerde bildirilmesine olanak tanır.

Bu yenilikler birlikte, üzerinde çalıştığınız türü tam olarak bilmenize gerek kalmadan matematiksel işlemleri genel olarak gerçekleştirmenizi sağlar. Örneğin, iki sayı ekleyen bir yöntem yazmak istiyorsanız, daha önce her tür için yöntemin aşırı yüklemesini eklemeniz gerekiyordu (örneğin, static int Add(int first, int second) ve static float Add(float first, float second)). Artık tür parametresinin sayı benzeri bir tür olarak kısıtlandığı tek bir genel yöntem yazabilirsiniz. Örneğin:

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

Bu yöntemde tür parametresi T , yeni INumber<TSelf> arabirimi uygulayan bir tür olacak şekilde kısıtlanır. INumber<TSelf>, + işlecini IAdditionOperators<TSelf,TOther,TResult>içeren arabirimini uygular. Bu, yöntemin iki sayıyı genel olarak eklemesine olanak tanır. yöntemi herhangi bir ile kullanılabilir. NET'in yerleşik sayısal türleridir çünkü bunların tümü .NET 7'de uygulanacak INumber<TSelf> şekilde güncelleştirilmiştir.

Kitaplık yazarları, "yedekli" aşırı yüklemeleri kaldırarak kod tabanını basitleştirebildiğinden, genel matematik arabirimlerinden en çok yararlanırlar. Kullandıkları API'ler daha fazla türü desteklemeye başlayabileceği için diğer geliştiriciler dolaylı olarak avantajlı olacaktır.

Arabirimler

Arabirimler, hem kullanıcıların kendi arabirimlerini en üstte tanımlayabilecek kadar ayrıntılı olacak şekilde tasarlanmıştır, hem de kullanımı kolay olacak kadar ayrıntılıdır. Bu ölçüde, ve gibi INumber<TSelf>IBinaryInteger<TSelf>kullanıcıların çoğuyla etkileşim kuracağı birkaç temel sayısal arabirim vardır. ve ITrigonometricFunctions<TSelf>gibi IAdditionOperators<TSelf,TOther,TResult> daha ayrıntılı arabirimler bu türleri destekler ve kendi etki alanına özgü sayısal arabirimlerini tanımlayan geliştiriciler tarafından kullanılabilir.

Sayısal arabirimler

Bu bölümde, içindeki sayı benzeri türleri ve bunlara sağlanan işlevleri açıklayan arabirimler System.Numerics açıklanmaktadır.

Arabirim adı Açıklama
IBinaryFloatingPointIeee754<TSelf> IEEE 754 standardını uygulayan ikili kayan nokta türleri1 için ortak API'leri kullanıma sunar.
IBinaryInteger<TSelf> İkili tamsayı 2 için ortak API'lerikullanıma sunar.
IBinaryNumber<TSelf> İkili sayılar için ortak API'leri kullanıma sunar.
IFloatingPoint<TSelf> Kayan nokta türleri için ortak API'leri kullanıma sunar.
IFloatingPointIeee754<TSelf> IEEE 754 standardını uygulayan kayan nokta türleri için ortak API'leri kullanıma sunar.
INumber<TSelf> Karşılaştırılabilir sayı türleriyle (etkili bir şekilde "gerçek" sayı etki alanı) ortak API'leri kullanıma sunar.
INumberBase<TSelf> Tüm sayı türlerinde ortak olan API'leri kullanıma sunar (etkili bir şekilde "karmaşık" sayı etki alanı).
ISignedNumber<TSelf> Tüm imzalı sayı türlerinde ortak olan API'leri (kavramı gibi NegativeOne) kullanıma sunar.
IUnsignedNumber<TSelf> tüm imzasız sayı türleri için ortak API'leri kullanıma sunar.
IAdditiveIdentity<TSelf,TResult> kavramını (x + T.AdditiveIdentity) == xkullanıma sunar.
IMinMaxValue<TSelf> ve T.MaxValuekavramını T.MinValue kullanıma sunar.
IMultiplicativeIdentity<TSelf,TResult> kavramını (x * T.MultiplicativeIdentity) == xkullanıma sunar.

1İkili kayan nokta türleri şunlardır Double : (double), Halfve Single (float).

2İkili tamsayı türleri şunlardır Byte : (byte), Int16 (short), Int32 (int), Int64 (long), Int128, IntPtr (nint), SByte (sbyte), UInt16 (ushort), UInt32UInt64 (uintulong), UInt128ve UIntPtr (nuint).

Doğrudan kullanma olasılığınız en yüksek olan arabirim, kabaca gerçek bir sayıya karşılık gelen arabirimidirINumber<TSelf>. Bir tür bu arabirimi uygularsa, bir değerin işareti (pozitif olarak kabul edilen türleri içerir unsigned ) ve aynı türdeki diğer değerlerle karşılaştırılabilir. INumberBase<TSelf>karmaşık ve sanal sayılar gibi daha gelişmiş kavramları( örneğin, negatif bir sayının karekökünü) ifade ediyor. Gibi IFloatingPointIeee754<TSelf>diğer arabirimler oluşturuldu çünkü tüm sayı türleri için tüm işlemler anlamlı değildir; örneğin, bir sayının tabanının hesaplanması yalnızca kayan nokta türleri için anlamlıdır. .NET temel sınıf kitaplığında kayan nokta türü Double uygular IFloatingPointIeee754<TSelf> ancak Int32 uygulamaz.

Arabirimlerin birkaçı, , , DateOnly, DecimalDateTimeGuidDateTimeOffset, TimeOnlyve TimeSpangibi Chardiğer çeşitli türler tarafından da uygulanır.

Aşağıdaki tabloda, her arabirim tarafından kullanıma sunulan bazı temel API'ler gösterilmektedir.

Arabirim API adı Açıklama
IBinaryInteger<TSelf> DivRem Bölüm ve kalan değerleri aynı anda hesaplar.
LeadingZeroCount İkili gösterimde baştaki sıfır bit sayısını sayar.
PopCount İkili gösterimdeki küme bitlerinin sayısını sayar.
RotateLeft Bitleri sola döndürür, bazen dairesel sol kaydırma olarak da adlandırılır.
RotateRight Bitleri sağa doğru döndürür ve bazen dairesel sağ kaydırma olarak da adlandırılır.
TrailingZeroCount İkili gösterimde sondaki sıfır bit sayısını sayar.
IFloatingPoint<TSelf> Ceiling Değeri pozitif sonsuzluğa yuvarlar. +4,5 +5, -4,5 ise -4 olur.
Floor Değeri negatif sonsuzluğa doğru yuvarlar. +4,5 +4, -4,5 ise -5 olur.
Round Belirtilen yuvarlama modunu kullanarak değeri yuvarlar.
Truncate Değeri sıfıra yuvarlar. +4,5 +4, -4,5 ise -4 olur.
IFloatingPointIeee754<TSelf> E Tür için Euler'ın numarasını temsil eden bir değer alır.
Epsilon Tür için sıfırdan büyük en küçük temsil edilebilir değeri alır.
NaN Türü temsil eden NaN bir değer alır.
NegativeInfinity Türü temsil eden -Infinity bir değer alır.
NegativeZero Türü temsil eden -Zero bir değer alır.
Pi Türü temsil eden Pi bir değer alır.
PositiveInfinity Türü temsil eden +Infinity bir değer alır.
Tau Türü temsil eden Tau (2 * Pi) bir değer alır.
(Diğer) (Altında listelenen tüm arabirim kümesini uygularİşlev arabirimleri.)
INumber<TSelf> Clamp Bir değeri belirtilen min ve max değerinden daha fazla ve en küçük değerle kısıtlar.
CopySign Belirtilen değerin işaretini, belirtilen başka bir değerle aynı olacak şekilde ayarlar.
Max Girdilerden NaNbiri ise döndürerek NaN iki değerin büyük bölümünü döndürür.
MaxNumber İki değerin büyük bir kısmını döndürür ve bir giriş ise NaNsayıyı döndürür.
Min Girişlerden biri NaNise döndürerek NaN iki değerin daha azını döndürür.
MinNumber İki değerin daha azını döndürür ve bir giriş ise NaNsayıyı döndürür.
Sign Negatif değerler için -1, sıfır için 0 ve pozitif değerler için +1 döndürür.
INumberBase<TSelf> One Türü için 1 değerini alır.
Radix Türün radiksini veya tabanını alır. Int32 2 döndürür. Decimal, 10'ü döndürür.
Zero Türün 0 değerini alır.
CreateChecked Girişin sığmayabileceği bir OverflowException değer oluşturarak bir değer oluşturur.1
CreateSaturating Giriş sığamıyorsa veya T.MaxValue öğesine sıkıştırarak T.MinValue bir değer oluşturur.1
CreateTruncating Başka bir değerden bir değer oluşturur ve girişin sığmaması durumunda çevresinde kaydırılır.1
IsComplexNumber Değer sıfır olmayan bir gerçek bölüme ve sıfır olmayan bir sanal bölüme sahipse true döndürür.
IsEvenInteger Değer çift tamsayıysa true döndürür. 2.0 döndürür trueve 2.2 döndürür false.
IsFinite Değer sonsuz değilse ve değilse NaNtrue döndürür.
IsImaginaryNumber Değerin gerçek bölümü sıfırsa true döndürür. Bu, hayali olduğu ve 1 + 1i olmadığı anlamına gelir0.
IsInfinity Değer sonsuzluğu temsil ederse true döndürür.
IsInteger Değer bir tamsayıysa true döndürür. 2.0 ve 3.0, true2.2 ve 3.1 ise döndürür false.
IsNaN değeri değerini temsil ederse NaNtrue döndürür.
IsNegative Değer negatifse true döndürür. Buna -0,0 dahildir.
IsPositive Değer pozitifse true döndürür. Buna 0 ve +0,0 dahildir.
IsRealNumber Değerin sıfır sanal bölümü varsa true döndürür. Bu, 0'ın tüm INumber<T> türlerde olduğu gibi gerçek olduğu anlamına gelir.
IsZero Değer sıfırı temsil ederse true döndürür. Buna 0, +0,0 ve -0,0 dahildir.
MaxMagnitude Daha büyük bir mutlak değere sahip değeri döndürür ve girişlerden biri ise NaNdöndürürNaN.
MaxMagnitudeNumber Mutlak değeri daha büyük olan değeri döndürür ve bir giriş ise NaNsayıyı döndürür.
MinMagnitude Girdilerden biri NaNise döndürerek NaN değeri daha az mutlak değerle döndürür.
MinMagnitudeNumber Değeri daha az mutlak değerle döndürür ve bir giriş ise NaNsayıyı döndürür.
ISignedNumber<TSelf> NegativeOne Türü için -1 değerini alır.

1Üç Create* yöntemin davranışını anlamanıza yardımcı olmak için aşağıdaki örnekleri göz önünde bulundurun.

Çok büyük bir değer verildiğinde örnek:

  • byte.CreateChecked(384) bir OverflowExceptionatar.
  • byte.CreateSaturating(384) 384 değerinden büyük Byte.MaxValue olduğundan (255 olan) 255 döndürür.
  • byte.CreateTruncating(384) en düşük 8 biti aldığından 128 döndürür (384'ün onaltılık 0x0180gösterimi vardır ve en düşük 8 bit 0x80128'dir).

Çok küçük bir değer verildiğinde örnek:

  • byte.CreateChecked(-384) bir OverflowExceptionatar.
  • byte.CreateSaturating(-384) - 384 küçük olduğundan Byte.MinValue (0 olan) 0 döndürür.
  • byte.CreateTruncating(-384) en düşük 8 biti aldığından 128 döndürür (384'ün onaltılık 0xFE80gösterimi vardır ve en düşük 8 bit 0x80128'dir).

Yöntemlerin Create* ayrıca ve gibi doublefloat IEEE 754 kayan nokta türleri için dikkat edilmesi gereken bazı özel noktalar vardır. Bunun için özel değerler , NegativeInfinityve NaNvardırPositiveInfinity. Üç Create* API de olarak CreateSaturatingdavranır. Ayrıca, ve MaxValue en büyük negatif/pozitif "normal" sayıyı temsil ederkenMinValue, gerçek minimum ve maksimum değerler ve PositiveInfinityşeklindedirNegativeInfinity, bu nedenle bunun yerine bu değerlere kelepçelenirler.

İşleç arabirimleri

İşleç arabirimleri, C# dili için kullanılabilen çeşitli işleçlere karşılık gelir.

  • Bu, tüm türler için doğru olmadığından çarpma ve bölme gibi işlemleri açıkça eşleştirmez. Örneğin, Matrix4x4 * Matrix4x4 geçerli, ancak Matrix4x4 / Matrix4x4 geçerli değil.
  • Genellikle giriş ve sonuç türlerinin, örneğin 3 / 2 = 1.5bir tamsayı elde etmek için iki tamsayıyı bölme veya bir doubletamsayı kümesinin ortalamasını hesaplama gibi senaryoları destekleyecek şekilde farklılık göstermesini sağlar.
Arabirim adı Tanımlı işleçler
IAdditionOperators<TSelf,TOther,TResult> x + y
IBitwiseOperators<TSelf,TOther,TResult> x & y, 'x | y', x ^ yve ~x
IComparisonOperators<TSelf,TOther,TResult> x < y, x > y, x <= yve x >= y
IDecrementOperators<TSelf> --x ve x--
IDivisionOperators<TSelf,TOther,TResult> x / y
IEqualityOperators<TSelf,TOther,TResult> x == y ve x != y
IIncrementOperators<TSelf> ++x ve x++
IModulusOperators<TSelf,TOther,TResult> x % y
IMultiplyOperators<TSelf,TOther,TResult> x * y
IShiftOperators<TSelf,TOther,TResult> x << y ve x >> y
ISubtractionOperators<TSelf,TOther,TResult> x - y
IUnaryNegationOperators<TSelf,TResult> -x
IUnaryPlusOperators<TSelf,TResult> +x

Not

Bazı arabirimler, normal işaretlenmemiş işleçlere ek olarak denetlenen bir işleç tanımlar. denetlenen işleçler, denetlenen bağlamlarda çağrılır ve kullanıcı tanımlı bir türün taşma davranışını tanımlamasına izin verir. denetlenen bir işleç uygularsanız, örneğin, CheckedSubtraction(TSelf, TOther)işaretlenmemiş işleci Subtraction(TSelf, TOther)de uygulamanız gerekir.

İşlev arabirimleri

İşlev arabirimleri, belirli bir sayısal arabirime göre daha geniş kapsamlı olarak uygulanan yaygın matematik API'lerini tanımlar. Bu arabirimlerin tümü tarafından IFloatingPointIeee754<TSelf>uygulanır ve gelecekte diğer ilgili türler tarafından uygulanabilir.

Arabirim adı Açıklama
IExponentialFunctions<TSelf> , e^x - 12^x - 12^x10^xve 10^x - 1destekleyen üstel işlevleri e^xkullanıma sunar.
IHyperbolicFunctions<TSelf> , asinh(x)cosh(x)atanh(x)sinh(x)ve tanh(x)destekleyen acosh(x)hiperbolik işlevleri kullanıma sunar.
ILogarithmicFunctions<TSelf> , ln(x + 1)log2(x + 1)log2(x)log10(x)ve log10(x + 1)destekleyen ln(x)logaritmik işlevleri kullanıma sunar.
IPowerFunctions<TSelf> destekleyen x^ygüç işlevlerini kullanıma sunar.
IRootFunctions<TSelf> ve sqrt(x)destekleyen cbrt(x) kök işlevleri kullanıma sunar.
ITrigonometricFunctions<TSelf> , , , cos(x)atan(x)asin(x)sin(x), ve tan(x)destekleyen trigonometrik işlevleri acos(x)kullanıma sunar.

Arabirimleri ayrıştırma ve biçimlendirme

Ayrıştırma ve biçimlendirme, programlamadaki temel kavramlardır. Bunlar genellikle kullanıcı girişini belirli bir türe dönüştürürken veya kullanıcıya bir tür görüntülerken kullanılır. Bu arabirimler ad alanındadır System .

Arabirim adı Açıklama
IParsable<TSelf> ve T.TryParse(string, IFormatProvider, out TSelf)için T.Parse(string, IFormatProvider) desteği kullanıma sunar.
ISpanParsable<TSelf> ve T.TryParse(ReadOnlySpan<char>, IFormatProvider, out TSelf)için T.Parse(ReadOnlySpan<char>, IFormatProvider) desteği kullanıma sunar.
IFormattable1 için value.ToString(string, IFormatProvider)desteği kullanıma sunar.
ISpanFormattable1 için value.TryFormat(Span<char>, out int, ReadOnlySpan<char>, IFormatProvider)desteği kullanıma sunar.

1Bu arabirim yeni değildir ve genel değildir. Ancak, tüm sayı türleri tarafından uygulanır ve ters işlemini IParsabletemsil eder.

Örneğin, aşağıdaki program giriş olarak iki sayı alır ve tür parametresinin kısıtlandığı IParsable<TSelf>genel bir yöntem kullanarak bunları konsoldan okur. Giriş ve sonuç değerlerinin tür parametrelerinin olarak kısıtlandığı INumber<TSelf>genel bir yöntem kullanarak ortalamayı hesaplar ve ardından sonucu konsolda görüntüler.

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
*/

Ayrıca bkz.