Kayan noktalı sayıdan tamsayıya dönüşümler doyumlu hale geliyor

Kayan noktadan tamsayıya dönüştürmeler artık x86 ve x64 makinelerinde doygunluk davranışına sahip. Doygunluk davranışı, dönüştürülen değerin hedef tür için çok küçük veya büyük olması durumunda değerin bu tür için sırasıyla en düşük veya en yüksek değere ayarlandığı anlamına gelir.

.NET 11'de bu davranış, CoreCLR'de (yorumlayıcısı dahil) ve Native AOT'da sbyte, byte, short, ushort ve char türlerine yönelik işaretlenmemiş dönüştürmeler için de geçerlidir, ancak Mono'da geçerli değildir. Ayrıntılar için bkz: Kayan noktalı sayıların küçük tamsayı türlerine dönüştürülmesi doygunluğa uğrar.

Önceki davranış

Aşağıdaki tabloda, bir float veya double değeri dönüştürülürken önceki davranış gösterilmektedir.

... biçimine dönüştür x değeri (Önceki) sonuç
int skaler ve paketlenmiş int.MinValue <= x <= int.MaxValue (int)x
< int.MinValue veya > int.MaxValue int.MinValue
long skaler ve paketlenmiş long.MinValue <= x <= long.MaxValue (long)x
< long.MinValue veya > long.MaxValue long.MinValue
uint skaler ve paketlenmiş Tüm değerler (((long)x << 32) >> 32)
ulong skaler ve paketlenmiş <= 2^63 (long)x
> 2^63 (long)(x - 2^63) + 2^63

Yeni davranış

Aşağıdaki tabloda, bir float veya double değerini dönüştürürken oluşan yeni davranış gösterilmektedir.

Dönüştür... x değeri .NET 9+ sonucu
int skaler ve paketlenmiş int.MinValue <= x <= int.MaxValue (int)x
< int.MinValue int.MinValue
> int.MaxValue int.MaxValue
NaN 0
long skaler ve paketli long.MinValue <= x <= long.MaxValue (long)x
< long.MinValue long.MinValue
> long.MaxValue long.MaxValue
NaN 0
uint skaler ve paketlenmiş 0 <= x <= uint.MaxValue (uint)x
x > uint.MaxValue uint.MaxValue
x < 0 0
ulong skaler ve paketli 0 <= x <= ulong.MaxValue (ulong)x
x > ulong.MaxValue ulong.MaxValue
x < 0 0

Sürüm kullanıma sunulmuştur

.NET 9 Önizleme 4

Uyumluluğu bozan değişiklik türü

Bu değişiklik davranışsal bir değişikliktir.

Değişiklik nedeni

Bu değişiklik, tüm kayan noktalı sayıdan tamsayıya dönüşümlerin doygunlaştırmalı davranış sergilemesini standartlaştırmak ve davranışı belirlenimci hale getirmek için yapıldı.

Dönüştürmeden, yanlış olsalar bile, Önceki davranış bölümünde gösterilen değerlerin döndürülmesine güveniyorsanız, kodunuzu Yeni davranış bölümünde gösterilen değerleri bekleyecek şekilde güncelleştirin.

Yeni davranışın performans yükü senaryonuz açısından istenmiyorsa, bunun yerine hızlı olan ConvertToIntegerNative<TInteger> yeni yöntemlerini Single, Double ve Half üzerinde kullanabilirsiniz. Çoğu durumda, bu yöntemlerin davranışı önceki kayan noktadan tamsayıya dönüştürme davranışıyla eşleşir. Ancak, bu yöntemler önceki dönüştürme davranışıyla (zaten belirleyici olmayan) eşleşmesi garanti edilmeyen platforma özgü davranışlara sahiptir. Bunun yerine, bu yöntemler yerel platform için en verimli olan her şeyi yapar. Özellikle, türün temsil edilebilir aralığının TInteger dışındaki değerler için sonuç garanti edilmez.

Performansa ve önceki dönüştürme davranışıyla eşleşmenin kesin garantisine ihtiyaç duyduğunuz nadir durumlarda platforma özgü donanım iç bilgilerini kullanabilirsiniz. Örneğin, (int)val öğesini float için işlemek üzere Sse.ConvertToInt32(Vector128.CreateScalar(val)) kullanabilirsiniz. Kullanmadan önce if (Sse.IsSupported) kontrol etmelisiniz. Ancak diğer hedef platformlar (arm64 gibi) zaten farklı sonuçlar ürettiği için bu iç bilgileri kullanmak karmaşıktır.

Etkilenen API’ler

Kayan noktadan tamsayıya tüm açık ve örtük atamalar:

  • (int)val burada val, float veya double'dir
  • Vector.ConvertToInt32(Vector<float> val)
  • (long)val burada val, bir float veya double'dir
  • Vector.ConvertToInt64(Vector<double> val)
  • (uint)valburada val, bir float veya double'dür
  • Vector.ConvertToUInt32(Vector<float> val)
  • (ulong)val burada val, float veya double'dir
  • Vector.ConvertToUInt64(Vector<double> val)