Trong Unreal, sự khác biệt giữa float của FF ++ và FFloat32 là gì?


17

Tôi đã cố gắng tìm hiểu một số khía cạnh sâu sắc hơn của UE4 và trong khi đọc nhiều mã ví dụ và cơ sở nguồn của công cụ, tôi nhận thấy rằng đôi khi mọi người (và chính mã nguồn) sử dụng floatnguyên hàm C ++ tiêu chuẩn , nhưng đôi khi sử dụng triển khai tùy chỉnh của UE4 FFloat32.

Sau đó, tôi đã tò mò: khi lập trình một trò chơi với Unreal, sự khác biệt giữa việc sử dụng 2 tùy chọn đó và có thể là những trường hợp chính nào khi người ta bỏ bản gốc C ++ tiêu chuẩn có lợi cho việc triển khai động cơ?


1
Tôi muốn đọc những ví dụ bạn thấy thực sự sử dụng FFloat32.

@JoshPetrie Một số người trong số họ đã ngoại tuyến, một cặp đôi đang trực tuyến. Ngay khi có thời gian ở nhà, tôi sẽ tìm kiếm họ để chia sẻ
Kim Shutter

Câu trả lời:


17

float, là tốt, một điểm nổi C ++. FFloat32là một cấu trúc đại diện cho một số float cũng như (thông qua một liên minh) các bitfield bị phân hủy cho dấu hiệu của phần float đó, phần mantissa và số mũ.

Bạn thường không bao giờ nên sử dụng FFloat32trừ khi:

  • bạn đang sử dụng một số API mong đợi FFloat32(những thứ này rất hiếm) hoặc
  • bạn cần thực hiện một số loại hack bit cấp thấp với giá trị dấu phẩy động (cũng khá hiếm trong những ngày này)

Không có gì FFloat32xấu cả , chỉ là nó không thực sự cung cấp cho bạn bất cứ thứ gì bạn cần cho việc sử dụng dấu phẩy động cho mục đích chung.

Nó ít phổ biến hơn so với một cái cũ đơn giản float, có một số tác động dễ đọc nhỏ (những người khác có thể không biết ngay nó là cái gì trong nháy mắt). Nó cũng không hoàn toàn chuyển đổi thành floatvì vậy bạn sẽ gõ something.FloatValuerất nhiều, đây cũng không phải là vấn đề lớn, nhưng có thể trở nên tẻ nhạt.

Cuối cùng, việc sử dụng các hiệp hội và bitfield của nó là không khả chuyển và được xác định theo triển khai (xem bên dưới). Đây không phải là vấn đề của bạn , công việc của Epic là đảm bảo loại được cấu trúc sao cho có thể sử dụng được cho tất cả các triển khai được hỗ trợ, nhưng đó là nguồn lỗi tiềm ẩn nếu chúng không gặp vấn đề với việc triển khai loại khi trình biên dịch mới phiên bản được phát hành hoặc thêm vào danh sách các trình biên dịch được hỗ trợ.

Vì vậy, trừ khi bạn có nhu cầu chơi với các bit riêng lẻ trong biểu diễn dấu phẩy động, có lẽ bạn chỉ nên tránh FFloat32(anh em họ của nó FFloat16, có thể có nhiều tiện ích hơn một chút vì không có loại dấu phẩy động C ++ 16 bit tiêu chuẩn).

Nó được sử dụng phổ biến để thao tác các float thông qua các biểu diễn số nguyên của các thành phần của chúng cho " tốc độ ". Các máy tính hiện đại không đáp ứng được nhiều nhu cầu cho nhiều nền tảng và các kỹ thuật xử lý kiểu khác nhau có thể được sử dụng để thực hiện loại điều này thực sự có thể gây bất lợi cho hiệu suất hoặc tính chính xác trong mọi sự kiện.

Cần phải nói rằng việc tìm kiếm kho lưu trữ GitHub của Unreal cho thấy rất ít cách sử dụng FFloat32loại này. Tất cả chúng đều nằm trong định nghĩa của FFloat32chính nó hoặc trong định nghĩa của FFloat16.


Cụ thể, FFloat32có hai điều mà tiêu chuẩn C ++ gọi ra. Nó:

  • cho phép bạn hành động như thể nhiều hơn một thành viên của liên minh hoạt động cùng một lúc; bạn sẽ viết cho các thành viên dấu phẩy động và đọc từ một trong các thành viên số nguyên (9.5.1, [class.union])
  • hy vọng phân bổ bitfield trong liên minh sẽ khớp với phân bổ bit của giá trị dấu phẩy động của IEEE; tuy nhiên, phân bổ và căn chỉnh của các thành viên bitfield trong một loại lớp được xác định thực hiện (9.6.1, [class.bit])

Unreal không được viết bằng C ++ tiêu chuẩn, nó được viết cho các trình biên dịch cụ thể mà nó được viết cho, miễn là chúng làm điều mong đợi thì tiêu chuẩn không liên quan.
dùng253751

Tôi hy vọng các bitfield đó sẽ khá di động ngay cả trong C / C ++ tiêu chuẩn, vì chúng được xác định bởi một tiêu chuẩn IEEE và bất kỳ trình biên dịch nào sử dụng bố cục khác floatsẽ không nhận được dấu đỏ tuân thủ theo chuẩn IEEE 754 (và các vấn đề tương thích với nhiều phần mềm hiện có ).
Dmitry Grigoryev

3
Vấn đề (phạm vi) là thứ tự bằng văn bản của các trường bit đó có thể khớp với tiêu chuẩn IEEE, nhưng trình biên dịch C ++ có thể sắp xếp lại hoặc sắp xếp lại chúng. Đây chỉ là một chú thích nhỏ mặc dù vì đối phó với đó là công việc của Epic; họ nên giám sát từng phiên bản trình biên dịch mới để xác minh loại hoạt động chính xác.

@JoshPetrie Điểm đã thực hiện, cảm ơn đã làm rõ.
Dmitry Grigoryev

1
@JustinLardinois Nhưng FFloat32 chứa một floatthành viên trong liên minh, vì vậy nếu floatthực sự lớn hơn 32 bit thì tổng thể FFloat32cũng sẽ như vậy vì liên minh phải đủ lớn để giữ thành viên lớn nhất. Trong trường hợp số float lớn hơn bốn byte, Epic sẽ phải sửa đổi các phần bitfield của liên minh để giải quyết điều đó, nếu không chúng sẽ không ánh xạ toàn bộ float.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.