UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
VVMFloat.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "HAL/Platform.h" // IWYU pragma: keep
7
8namespace Verse
9{
10struct VValue;
11
12// Encapsulates a Verse float, which has a few deviations from IEEE-754 semantics for the sake of
13// providing extensional equality; i.e. that iff two values compare as equal, there's no way to
14// distinguish them.
15//
16// IEEE-754 floats don't have extensional equality for two reasons:
17// - Zeroes of opposite signs compare as equal, but when used as a divisor produce different infinities.
18// - NaNs compare as unequal to themselves.
19// We resolve this by defining division by negative zero to produce positive infinity, and collapsing
20// NaNs to a single canonical NaN that compares as equal to itself and unordered with all numbers.
21struct VFloat
22{
23 friend struct VValue;
24
25 // Default initialize to zero.
26 constexpr VFloat()
27 : Value(0.0)
28 {
29 }
30
31 explicit VFloat(double InValue)
32 : Value(InValue)
33 {
34 }
35
36 static VFloat NaN()
37 {
38 return BitCast<VFloat>(0x7ff8'0000'0000'0000);
39 }
40
42 {
43 return BitCast<VFloat>(0x7ff0'0000'0000'0000);
44 }
45
46 double AsDouble() const
47 {
48 return NormalizeSignedZero().Value;
49 }
50
52 {
53 return BitCast<uint64>(Value);
54 }
55
56 // Purify a potentially impure float (as defined by VValue).
58
59 // Predicates for different FP specials.
60 COREPRECISEFP_API bool IsFinite() const;
61 COREPRECISEFP_API bool IsInfinite() const;
62 COREPRECISEFP_API bool IsNaN() const;
63
64 // Arithmetic operations in a non-fast-math environment (IEEE compliant).
65 // These can (mostly) be removed when callers are guaranteed to not be
66 // compiled with fast-math or similar enabled.
67 friend constexpr VFloat operator+(VFloat Operand)
68 {
69 return Operand;
70 }
76
78 {
79 return *this = *this + Right;
80 }
82 {
83 return *this = *this - Right;
84 }
86 {
87 return *this = *this * Right;
88 }
90 {
91 return *this = *this / Right;
92 }
93
94 // We use an ordering relationship different from the default IEEE float
95 // ordering (because we require NaNs to compare equal to each other).
99
100 // The remaining relations can be inferred from the relations above.
101
102 friend inline bool operator!=(VFloat Left, VFloat Right)
103 {
104 return !(Left == Right);
105 }
106
107 friend inline bool operator>(VFloat Left, VFloat Right)
108 {
109 return Right < Left;
110 }
111
112 friend inline bool operator>=(VFloat Left, VFloat Right)
113 {
114 return Right <= Left;
115 }
116
117 // Ranking function that turns a double into an int64 that defines a total order
118 // compatible with the ordering implied for floats, to be precise
119 //
120 // a < b => Ranking(a) < Ranking(b)
121 // a == b <=> Ranking(a) == Ranking(b)
122 //
123 // For Less(a,b), we only have implication in one direction because when a single
124 // NaN is involved, the strict "less" ordering relationship is partial. In the total
125 // order implied by Ranking, NaN compares larger than all other floats. Unlike
126 // normal IEEE semantics, NaNs compare equal to each other in our ordering, so for
127 // Equal we have full equivalence.
128 //
129 // Ranking can be used directly or as a key for sorted maps and hashes.
131
132private:
133 double Value;
134
135 COREPRECISEFP_API VFloat NormalizeSignedZero() const;
136};
137} // namespace Verse
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
Definition Archive.h:36
Definition VVMFloat.h:22
VFloat & operator-=(VFloat Right)
Definition VVMFloat.h:81
COREPRECISEFP_API bool IsFinite() const
Definition VVMFloat.cpp:44
VFloat & operator*=(VFloat Right)
Definition VVMFloat.h:85
COREPRECISEFP_API VFloat Purify() const
Definition VVMFloat.cpp:11
friend struct VValue
Definition VVMFloat.h:23
COREPRECISEFP_API friend bool operator<=(VFloat Left, VFloat Right)
Definition VVMFloat.cpp:102
double AsDouble() const
Definition VVMFloat.h:46
COREPRECISEFP_API int64 Ranking() const
Definition VVMFloat.cpp:118
friend constexpr VFloat operator+(VFloat Operand)
Definition VVMFloat.h:67
COREPRECISEFP_API friend bool operator==(VFloat Left, VFloat Right)
Definition VVMFloat.cpp:81
COREPRECISEFP_API friend bool operator<(VFloat Left, VFloat Right)
Definition VVMFloat.cpp:94
friend bool operator>(VFloat Left, VFloat Right)
Definition VVMFloat.h:107
constexpr VFloat()
Definition VVMFloat.h:26
VFloat(double InValue)
Definition VVMFloat.h:31
VFloat & operator/=(VFloat Right)
Definition VVMFloat.h:89
COREPRECISEFP_API friend VFloat operator/(VFloat Left, VFloat Right)
Definition VVMFloat.cpp:37
static VFloat NaN()
Definition VVMFloat.h:36
friend bool operator!=(VFloat Left, VFloat Right)
Definition VVMFloat.h:102
VFloat & operator+=(VFloat Right)
Definition VVMFloat.h:77
friend bool operator>=(VFloat Left, VFloat Right)
Definition VVMFloat.h:112
uint64 ReinterpretAsUInt64() const
Definition VVMFloat.h:51
COREPRECISEFP_API friend VFloat operator-(VFloat Operand)
Definition VVMFloat.cpp:17
COREPRECISEFP_API bool IsInfinite() const
Definition VVMFloat.cpp:49
static VFloat Infinity()
Definition VVMFloat.h:41
COREPRECISEFP_API friend VFloat operator*(VFloat Left, VFloat Right)
Definition VVMFloat.cpp:32
COREPRECISEFP_API bool IsNaN() const
Definition VVMFloat.cpp:58