Di Unreal, apa perbedaan antara float C ++ dan FFloat32?

17

Saya telah mencoba mempelajari beberapa aspek yang lebih dalam dari UE4 dan ketika membaca banyak contoh kode dan juga basis sumber dari mesin, saya perhatikan bahwa kadang-kadang orang (dan kode sumber) menggunakan standar C ++ floatprimitif, tetapi kadang-kadang menggunakan implementasi kustom UE4 FFloat32.

Lalu saya jadi penasaran: ketika memprogram permainan dengan Unreal, apa perbedaan antara menggunakan 2 opsi itu dan mungkin apa kasus utama ketika seseorang harus menjatuhkan standar C ++ primitif demi implementasi mesin?

Kim Shutter
sumber
1
Saya akan tertarik membaca contoh yang Anda temukan yang benar-benar digunakan FFloat32.
@JoshPetrie Beberapa dari mereka offline, beberapa online. Segera setelah saya punya waktu di rumah, saya akan mencari mereka untuk dibagikan
Kim Shutter

Jawaban:

17

float, adalah titik mengambang C ++. FFloat32adalah struktur yang mewakili float serta (melalui penyatuan) bitfields yang terurai untuk tanda float itu, mantissa dan bagian eksponen.

Anda umumnya tidak boleh menggunakan FFloat32kecuali ketika:

  • Anda menggunakan beberapa API yang mengharapkan FFloat32(ini sangat jarang) atau
  • Anda perlu melakukan semacam peretasan bit tingkat rendah dengan nilai floating point (juga cukup langka hari ini)

Ini bukan berarti bahwa FFloat32adalah buruk , per se, itu hanya bahwa itu tidak benar-benar menawarkan apa pun yang Anda akan perlu untuk tujuan umum floating penggunaan titik.

Ini lebih jarang daripada yang biasa float, yang memiliki beberapa dampak keterbacaan kecil (yang lain mungkin tidak tahu langsung untuk apa sekilas pandang). Ini juga tidak secara implisit dikonversi ke floatsehingga Anda akan banyak mengetik something.FloatValue, yang juga bukan masalah besar, tetapi bisa membosankan.

Akhirnya, penggunaan serikat pekerja dan bitfields adalah non-portabel, dan implementasi-didefinisikan (lihat di bawah). Ini bukan masalah Anda , itu adalah tugas Epic untuk memastikan tipe terstruktur sehingga dapat digunakan untuk semua implementasi yang didukung, tetapi ini merupakan sumber bug potensial jika mereka gagal menangkap masalah dengan implementasi tipe ketika kompiler baru versi dirilis atau ditambahkan ke daftar kompiler yang didukung.

Jadi, kecuali Anda memiliki kebutuhan untuk bermain dengan bit individu dalam representasi floating point, Anda mungkin harus menghindari FFloat32(sepupunya FFloat16,, mungkin memiliki utilitas sedikit lebih karena tidak ada standar 16-bit C ++ tipe floating point).

Dulu umum untuk memanipulasi pelampung melalui representasi integer dari komponen mereka untuk " kecepatan ." Komputer modern menyingkirkan banyak kebutuhan itu untuk banyak platform, dan berbagai jenis teknik penghukuman yang dapat digunakan untuk melakukan hal semacam ini sebenarnya dapat merusak kinerja atau kebenaran dalam peristiwa apa pun.

Seharusnya memberitahu bahwa pencarian repositori Unit's GitHub mengungkapkan sangat sedikit kegunaan dari FFloat32tipe tersebut. Semuanya dalam definisi FFloat32itu sendiri atau dalam definisi FFloat16.


Secara khusus, FFloat32melakukan dua hal yang disebut oleh standar C ++. Itu:

  • memungkinkan Anda untuk bertindak seolah-olah lebih dari satu anggota serikat aktif pada satu waktu; Anda diharapkan menulis kepada anggota floating point dan membaca dari salah satu anggota integer (9.5.1, [class.union])
  • mengharapkan alokasi bitfield dalam serikat untuk mencocokkan dengan alokasi bit dari nilai titik mengambang IEEE; namun demikian, alokasi dan penyelarasan anggota bitfield dalam tipe kelas ditentukan oleh implementasi (9.6.1, [class.bit])

sumber
Unreal tidak ditulis dalam standar C ++, ini ditulis untuk kompiler khusus yang ditulis untuknya, jadi selama mereka melakukan hal yang diharapkan, standar tidak relevan.
user253751
Saya berharap bitfields tersebut cukup portabel bahkan dalam standar C / C ++, karena mereka didefinisikan oleh standar IEEE, dan setiap kompiler yang menggunakan tata letak yang berbeda tidak floatakan mendapatkan tanda merah yang memenuhi syarat IEEE 754 (dan masalah kompatibilitas dengan banyak perangkat lunak yang ada) ).
Dmitry Grigoryev
3
Masalah (pedantic) adalah bahwa urutan tertulis dari bidang bit tersebut mungkin cocok dengan standar IEEE, tetapi kompiler C ++ dapat memesan ulang atau menyelaraskannya kembali. Ini hanya catatan kaki kecil karena berurusan dengan itu adalah pekerjaan Epic; mereka harus memantau setiap versi kompiler baru untuk memverifikasi bahwa jenisnya berfungsi dengan benar.
@JoshPetrie Point diambil, terima kasih atas klarifikasi.
Dmitry Grigoryev
1
@JustinLardinois Tapi FFloat32 berisi floatanggota dalam serikat pekerja, jadi jika floatsebenarnya lebih besar dari 32 bit, keseluruhannya FFloat32akan baik karena serikat pekerja harus cukup besar untuk menampung anggota terbesar. Dalam kasus di mana float lebih besar dari empat byte, Epic harus memodifikasi bagian bitfield dari union juga untuk mengatasinya, jika tidak mereka tidak akan memetakan float lengkap.