Aracılığıyla paylaş


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 virtualsağ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 içeren IAdditionOperators<TSelf,TOther,TResult> arabirimini uygular. Bu, yöntemin iki sayıyı genel olarak eklemesine olanak tanır. Bu yöntem, .NET'in yerleşik sayısal türlerinden herhangi biriyle kullanılabilir, çünkü bunların tümü .NET 7'de INumber<TSelf>'yi kullanacak şekilde güncellenmiş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. Kullanıcıların çoğunun etkileşim kuracağı, örneğin INumber<TSelf> ve IBinaryInteger<TSelf> gibi birkaç temel sayısal arabirim vardır. Daha ayrıntılı arabirimler, örneğin IAdditionOperators<TSelf,TOther,TResult> ve ITrigonometricFunctions<TSelf>, 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, System.Numerics içindeki sayı benzeri türleri ve bunlara sağlanan işlevleri açıklayan arabirimler anlatılmaktadı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'leri kullanı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ürlerine ortak olan API'leri (etkili olarak "gerçek" sayı alanı) kullanıma sunar.
INumberBase<TSelf> Sayı türlerinin tamamında ortak olan API'leri sunar (fonksiyonel olarak "karmaşık" sayı alanı).
ISignedNumber<TSelf> Tüm imzalı sayı türleri için ortak olan API'leri (örneğin NegativeOne kavramı gibi) kullanıma sunar.
IUnsignedNumber<TSelf> tüm imzasız sayı türleri için ortak API'leri kullanıma sunar.
IAdditiveIdentity<TSelf,TResult> (x + T.AdditiveIdentity) == x kavramını açığa çıkarır.
IMinMaxValue<TSelf> T.MinValue ve T.MaxValue kavramını ortaya koyar.
IMultiplicativeIdentity<TSelf,TResult> (x * T.MultiplicativeIdentity) == x kavramını açığa çıkarır.

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

2İkili tamsayı türleri şunlardır: Byte (byte), Int16 (short), Int32 (int), Int64 (long), Int128, IntPtr (nint), SByte (sbyte), UInt16 (ushort), UInt32 (uint), UInt64 (ulong), UInt128, ve UIntPtr (nuint).

Doğrudan kullanma olasılığınız en yüksek olan arabirim, kabaca INumber<TSelf> bir sayıya karşılık gelen arabirimidir. Bir tür bu arabirimi uygularsa, bu, bir değerin işareti olduğu (pozitif kabul edilen unsigned türlerini içerir) ve bu değerin aynı türdeki diğer değerlerle karşılaştırılabilir olduğu anlamına gelir. INumberBase<TSelf> karmaşık vesanal 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.

Birçok arayüz, çeşitli diğer türler dahil olmak üzere Char, DateOnly, DateTime, DateTimeOffset, Decimal, Guid, TimeOnly ve TimeSpan tarafından da uygulanmaktadır.

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

Arayüz 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 döndürür; bazen bu işlem 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 olan en küçük temsil edilebilir değeri alır.
NaN Tür için NaN değerini temsil eden bir değer alır.
NegativeInfinity Tür için -Infinity değerini temsil eden bir değer alır.
NegativeZero Tür için -Zero değerini temsil eden bir değer alır.
Pi Tür için Pi değerini temsil eden bir değer alır.
PositiveInfinity Tür için +Infinity değerini temsil eden bir değer alır.
Tau Türü temsil eden Tau (2 * Pi) bir değer alır.
(Diğer) (İşlev arabirimleri altında listelenen arabirimlerin tamamını uygular.)
INumber<TSelf> Clamp Belirtilen minimum ve maksimum değerler arasında bir değeri sınırlar.
CopySign Belirtilen değerin işaretini, belirtilen başka bir değerle aynı olacak şekilde ayarlar.
Max İki değerden büyük olanını döndürür; girdilerden biri NaN ise NaN döndürülür.
MaxNumber İki değerden büyük olanı döndürür; eğer biri NaN ise sayıyı döndürür.
Min İki değerden hangisi daha küçükse onu döndürür, ancak girişlerden biri NaN ise NaN döndürür.
MinNumber İki değerden küçüğünü döndürür, eğer bir giriş NaN ise sayı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 için 0 değerini elde eder.
CreateChecked Giriş sığmazsa bir OverflowException fırlatarak bir değer oluşturur.1
CreateSaturating Giriş sığmazsa, değeri T.MinValue veya T.MaxValue öğesine sıkıştırarak 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 NaN değilse true döndürür.
IsImaginaryNumber Değerin gerçek bölümü sıfırsa true döndürür. Bu, 0 hayali olduğu ve 1 + 1i olmadığı anlamına gelir.
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, true döndürür ve 2.2 ve 3.1, false döndürür.
IsNaN Değer NaN değerini temsil ediyorsa true 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 Mutlak değeri daha büyük olan değeri döndürür, eğer girişlerden biri NaN ise NaN döndürür.
MaxMagnitudeNumber Mutlak değeri daha büyük olan değeri döndürür, ayrıca bir giriş NaN ise, o sayıyı döndürür.
MinMagnitude Girdilerden biri NaN ise, NaN döndürülür; aksi takdirde, mutlak değeri daha küçük olan değeri döndürür.
MinMagnitudeNumber Daha düşük mutlak değere sahip olan değeri döndürür, eğer bir giriş NaN ise sayıyı döndürür.
ISignedNumber<TSelf> NegativeOne Türün -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.
  • 384, byte.CreateSaturating(384) (ki bu 255'tir) değerinden büyük olduğu için Byte.MaxValue 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 Byte.MinValue'den küçük olduğu için 0 olarak döner (ki bu 0'dı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).

IEEE 754 kayan nokta türleri olan Create* ve float için, double, PositiveInfinity ve NegativeInfinity gibi özel değerlere dikkat edilmesi gereken bazı özel noktalar vardır. Üç Create* API de CreateSaturating olarak davranır. Ayrıca, MinValue ve MaxValue en büyük negatif/pozitif "normal" sayıyı temsil ederken, gerçek minimum ve maksimum değerler NegativeInfinity ve PositiveInfinity şeklindedir, bu nedenle bunun yerine bu değerlere sınırlanırlar.

İş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 doublebir tamsayı elde etmek için iki tamsayıyı bölme veya bir 3 / 2 = 1.5tamsayı 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 ^ y ve ~x
IComparisonOperators<TSelf,TOther,TResult> x < y, x > y, x <= y ve 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

Uyarı

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), denetimsiz işleci de uygulamanız gerekir, örneğin, Subtraction(TSelf, TOther).

İşlev arabirimleri

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

Arabirim adı Açıklama
IExponentialFunctions<TSelf> e^x, e^x - 1, 2^x, 2^x - 1, 10^x, ve 10^x - 1 destekleyen üstel işlevleri kullanıma sunar.
IHyperbolicFunctions<TSelf> acosh(x) hiperbolik işlevlerini asinh(x), atanh(x), cosh(x), sinh(x) ve tanh(x) destekleyen şekilde kullanıma sunar.
ILogarithmicFunctions<TSelf> ln(x), ln(x + 1), log2(x), log2(x + 1), log10(x) ve log10(x + 1) destekleyen logaritmik işlevleri kullanıma sunar.
IPowerFunctions<TSelf> x^y destekleyen güç fonksiyonlarını kullanıma sunar.
IRootFunctions<TSelf> cbrt(x) ve sqrt(x) için destekleyen kök işlevleri kullanıma sunar.
ITrigonometricFunctions<TSelf> acos(x), asin(x), atan(x), cos(x), sin(x) ve tan(x) destekleyen trigonometrik işlevleri 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 System ad alanında yer almaktadır.

Arabirim adı Açıklama
IParsable<TSelf> T.Parse(string, IFormatProvider) ve T.TryParse(string, IFormatProvider, out TSelf) için desteği sağlar.
ISpanParsable<TSelf> T.Parse(ReadOnlySpan<char>, IFormatProvider) ve T.TryParse(ReadOnlySpan<char>, IFormatProvider, out TSelf) için desteği sağlar.
IFormattable 1 value.ToString(string, IFormatProvider) desteğini sunar.
ISpanFormattable 1 value.TryFormat(Span<char>, out int, ReadOnlySpan<char>, IFormatProvider) desteğini sunar.

1Bu arabirim yeni değildir ve genel değildir. Ancak, tüm sayı türleri tarafından uygulanır ve IParsable ters işlemini temsil 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 bakınız