Bagikan melalui


Konversi titik-ke-bilangan bulat mengambang menjenuhkan

Konversi titik-ke-bilangan bulat mengambang sekarang memiliki perilaku menjenuhkan pada mesin x86 dan x64. Perilaku jenuh berarti bahwa jika nilai yang dikonversi terlalu kecil atau besar untuk jenis target, nilai diatur ke nilai minimum atau maksimum, masing-masing, untuk jenis tersebut.

Perilaku sebelumnya

Tabel berikut ini memperlihatkan perilaku sebelumnya saat mengonversi float nilai atau double .

Konversi ke ... nilai x Hasil (Sebelumnya)
int skalar dan dikemas int.MinValue <= x <= int.MaxValue (int)x
< int.MinValue atau > int.MaxValue int.MinValue
long skalar dan dikemas long.MinValue <= x <= long.MaxValue (long)x
< long.MinValue atau > long.MaxValue long.MinValue
uint skalar dan dikemas Nilai apa pun (((long)x << 32) >> 32)
ulong skalar dan dikemas <= 2^63 (long)x
> 2^63 (long)(x - 2^63) + 2^63

Perilaku yang baru

Tabel berikut ini memperlihatkan perilaku baru saat mengonversi float nilai atau double .

Konversi ke ... nilai x Hasil .NET 9+
int skalar dan dikemas int.MinValue <= x <= int.MaxValue (int)x
< int.MinValue int.MinValue
> int.MaxValue int.MaxValue
NaN 0
long skalar dan dikemas long.MinValue <= x <= long.MaxValue (long)x
< long.MinValue long.MinValue
> long.MaxValue long.MaxValue
NaN 0
uint skalar dan dikemas 0 <= x <= uint.MaxValue (uint)x
x > uint.MaxValue uint.MaxValue
x < 0 0
ulong skalar dan dikemas 0 <= x <= ulong.MaxValue (ulong)x
x > ulong.MaxValue ulong.MaxValue
x < 0 0

Versi yang diperkenalkan

Pratinjau .NET 9 4

Jenis perubahan yang melanggar

Perubahan ini adalah perubahan perilaku.

Alasan untuk berubah

Perubahan ini dilakukan untuk menstandarkan semua konversi floating point-to-integer untuk memiliki perilaku jenuh dan untuk membuat perilaku menjadi deterministik.

Jika Anda mengandalkan nilai yang ditampilkan di bagian Perilaku sebelumnya untuk dikembalikan dari konversi, meskipun salah, perbarui kode Anda untuk mengharapkan nilai yang ditampilkan di bagian Perilaku baru.

Jika overhead performa perilaku baru tidak diinginkan untuk skenario Anda, Anda dapat menggunakan metode baru ConvertToIntegerNative<TInteger> pada Tunggal, Ganda, dan Setengah sebagai gantinya, yang cepat. Dalam kebanyakan kasus, perilaku metode ini cocok dengan perilaku konversi titik-ke-bilangan bulat mengambang sebelumnya. Namun, metode ini memiliki perilaku khusus platform yang tidak dijamin cocok dengan perilaku konversi sebelumnya (yang sudah tidak deterministik). Sebaliknya, metode ini melakukan apa pun yang paling efisien untuk platform asli. Terutama, hasilnya tidak dijamin untuk nilai yang berada di luar rentang jenis yang dapat diwakili TInteger .

Dalam kasus yang jarang terjadi di mana Anda membutuhkan performa dan jaminan ketat untuk mencocokkan perilaku konversi sebelumnya, Anda dapat menggunakan intrinsik perangkat keras khusus platform. Misalnya, Anda dapat menggunakan Sse.ConvertToInt32(Vector128.CreateScalar(val)) untuk menangani (int)val .float Anda harus memeriksa if (Sse.IsSupported) sebelum menggunakan. Namun, menggunakan intrinsik ini sulit, karena platform target lain (Arm64) sudah menghasilkan hasil yang berbeda.

API yang Terpengaruh

Semua cast eksplisit dan implisit dari floating point ke bilangan bulat:

  • (int)val di mana val adalah float atau double
  • Vector.ConvertToInt32(Vector<float> val)
  • (long)val di mana val adalah float atau double
  • Vector.ConvertToInt64(Vector<double> val)
  • (uint)val di mana val adalah float atau double
  • Vector.ConvertToUInt32(Vector<float> val)
  • (ulong)val di mana val adalah float atau double
  • Vector.ConvertToUInt64(Vector<double> val)