ใน Unreal ความแตกต่างระหว่าง C ++ กับ float คือ FFloat32 คืออะไร?


17

ฉันพยายามที่จะเรียนรู้บางแง่มุมที่ลึกซึ้งยิ่งขึ้นของ UE4 และในขณะที่อ่านรหัสตัวอย่างจำนวนมากและยังเป็นแหล่งที่มาของเครื่องยนต์ฉันสังเกตว่าบางครั้งผู้คน (และซอร์สโค้ดมาก) ใช้มาตรฐานfloatดั้งเดิมC ++ แต่บางครั้งก็ใช้FFloat32.

ถ้าอย่างนั้นฉันอยากรู้ว่า: เมื่อเขียนโปรแกรมเกมด้วย Unreal อะไรคือความแตกต่างระหว่างการใช้ 2 ตัวเลือกเหล่านี้และสิ่งที่เป็นกรณีหลักที่ควรวางมาตรฐานดั้งเดิม C ++ แบบดั้งเดิมเพื่อการใช้งานของเครื่องยนต์


1
FFloat32ฉันจะให้ความสนใจในการอ่านตัวอย่างที่คุณได้พบว่าการใช้งานจริง

@JoshPetrie บางคนออฟไลน์คู่ออนไลน์ ทันทีที่ฉันมีเวลาอยู่ที่บ้านฉันจะค้นหาพวกเขาเพื่อแบ่งปัน
Kim Shutter

คำตอบ:


17

floatเป็นอย่างดีจุดลอยตัว C ++ FFloat32เป็นโครงสร้างที่แสดงถึงการลอยเช่นเดียวกับ (ผ่านทางสหภาพ) bitfields ที่สลายตัวสำหรับสัญญาณของลอย mantissa และชิ้นส่วนเลขชี้กำลัง

คุณควรทั่วไปไม่เคยใช้FFloat32ยกเว้นเมื่อ:

  • คุณกำลังใช้ API บางอย่างที่คาดหวังFFloat32(อันนี้หายากมาก) หรือ
  • คุณต้องทำการแฮ็คบิตระดับต่ำด้วยค่าคะแนนลอยตัว (ซึ่งหาได้ยากในสมัยนี้)

มันไม่ได้ว่าFFloat32เป็นที่ไม่ดีต่อ se ก็เพียงว่ามันไม่ได้โดดให้คุณสิ่งที่คุณต้องการเพื่อให้การใช้งานจุดลอยวัตถุประสงค์ทั่วไป

มันเป็นเรื่องธรรมดาน้อยกว่าเก่าธรรมดาfloatซึ่งมีผลกระทบต่อการอ่านเล็กน้อย (คนอื่นอาจไม่ทราบทันทีว่ามันคืออะไรสำหรับภาพรวม) นอกจากนี้ยังไม่แปลงโดยปริยายเพื่อfloatให้คุณพิมพ์ได้something.FloatValueมากซึ่งไม่ใช่เรื่องใหญ่ แต่ก็น่าเบื่อ

ในที่สุดการใช้งานของสหภาพแรงงานและ bitfields นั้นไม่สามารถพกพาได้และมีการกำหนดการใช้งาน (ดูด้านล่าง) นี่ไม่ใช่ปัญหาของคุณมันเป็นงานของ Epic เพื่อให้แน่ใจว่ามีโครงสร้างประเภทนั้นเพื่อให้สามารถใช้งานได้สำหรับการใช้งานทั้งหมดที่ได้รับการสนับสนุน แต่เป็นแหล่งที่มาของข้อบกพร่องหากพวกเขาล้มเหลวในการตรวจสอบปัญหา รุ่นวางจำหน่ายหรือเพิ่มลงในรายการคอมไพเลอร์ที่รองรับ

ดังนั้นหากคุณไม่จำเป็นต้องเล่นกับแต่ละบิตในการเป็นตัวแทนจุดลอยตัวคุณก็ควรหลีกเลี่ยงFFloat32(ลูกพี่ลูกน้องของมันFFloat16อาจมีประโยชน์มากกว่าเล็กน้อยเนื่องจากไม่มีประเภทจุดลอยตัวมาตรฐาน C-16 บิต)

มันเคยเป็นเรื่องธรรมดาที่จะจัดการกับการลอยผ่านตัวแทนจำนวนเต็มขององค์ประกอบของพวกเขาสำหรับ " ความเร็ว " คอมพิวเตอร์สมัยใหม่ตัดขาดสิ่งที่จำเป็นสำหรับแพลตฟอร์มจำนวนมากและเทคนิคการสะกดรอยพิมพ์ต่าง ๆที่สามารถใช้ในการทำสิ่งต่าง ๆ เหล่านี้ได้จริงอาจเป็นอันตรายต่อประสิทธิภาพหรือความถูกต้องในทุกกรณี

มันควรจะบอกว่าการค้นหาคลังเก็บ GitHub ของ Unreal เผยให้เห็นการใช้งานของFFloat32ประเภทน้อยมาก ทั้งหมดของพวกเขาอยู่ในความหมายของ ตัวเองหรือในความหมายของFFloat32FFloat16


โดยเฉพาะFFloat32ทำสองสิ่งที่มาตรฐาน C ++ เรียกใช้ มัน:

  • อนุญาตให้คุณทำราวกับว่าสมาชิกสหภาพมากกว่าหนึ่งคนกำลังทำงานอยู่ในคราวเดียว คุณคาดว่าจะเขียนถึงสมาชิกทศนิยมและอ่านจากหนึ่งในสมาชิกจำนวนเต็ม (9.5.1, [class.union])
  • คาดหวังการจัดสรรบิตฟิลด์ภายในสหภาพเพื่อให้ตรงกับการจัดสรรบิตของค่าทศนิยมของ IEEE อย่างไรก็ตามการจัดสรรและการจัดตำแหน่งของสมาชิก bitfield ภายในประเภทคลาสนั้นมีการกำหนดการใช้งาน (9.6.1, [class.bit])

ลวงตาไม่ได้เขียนในมาตรฐาน C ++ มันถูกเขียนขึ้นสำหรับคอมไพเลอร์เฉพาะที่เขียนขึ้นดังนั้นตราบใดที่พวกเขาทำในสิ่งที่คาดหวังมาตรฐานก็ไม่เกี่ยวข้อง
user253751

ฉันคาดหวังว่าบิตฟิลด์เหล่านั้นจะค่อนข้างพกพาได้แม้จะอยู่ในมาตรฐาน C / C ++ เนื่องจากมันถูกกำหนดโดยมาตรฐาน IEEE และคอมไพเลอร์ใด ๆ ที่ใช้เลย์เอาต์ที่แตกต่างกันfloatจะไม่ได้เครื่องหมายสีแดงตามมาตรฐาน IEEE 754 )
Dmitry Grigoryev

3
ปัญหา (pedantic) คือคำสั่งเขียนของเขตข้อมูลบิตเหล่านั้นอาจตรงกับมาตรฐาน IEEE แต่คอมไพเลอร์ C ++ อาจเรียงลำดับใหม่หรือจัดเรียงใหม่ นี่เป็นเพียงเชิงอรรถเล็ก ๆ น้อย ๆ แต่นับตั้งแต่จัดการกับงานของ Epic; พวกเขาควรจะตรวจสอบคอมไพเลอร์เวอร์ชั่นใหม่แต่ละรุ่นเพื่อตรวจสอบว่าประเภททำงานอย่างถูกต้องหรือไม่

@JoshPetrie Point ได้รับขอบคุณสำหรับคำชี้แจง
Dmitry Grigoryev

1
@JustinLardinois แต่ FFloat32 มีfloatสมาชิกอยู่ในกลุ่มดังนั้นหากfloatจริง ๆ แล้วมีขนาดใหญ่กว่า 32 บิตโดยรวมFFloat32จะเป็นเช่นเดียวกันเนื่องจากสหภาพต้องมีขนาดใหญ่พอที่จะเป็นสมาชิกที่ใหญ่ที่สุด ในกรณีที่การลอยตัวมีขนาดใหญ่กว่าสี่ไบต์ Epic จะต้องแก้ไขส่วน bitfield ของสหภาพเช่นกันเพื่อแก้ไขปัญหานั้นมิฉะนั้นพวกเขาจะไม่แมปการลอยทั้งหมด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.