MCPcopy Create free account
hub / github.com/apache/fory / to_float

Method to_float

cpp/fory/util/float16.cc:120–178  ·  view source on GitHub ↗

Convert float16 to float32 (exact: every f16 value is representable in f32).

Source from the content-addressed store, hash-verified

118
119// Convert float16 to float32 (exact: every f16 value is representable in f32).
120float float16_t::to_float() const noexcept {
121 const uint32_t sign = static_cast<uint32_t>(bits & 0x8000u) << 16;
122 const uint32_t exp = (bits >> 10) & 0x1Fu;
123 const uint32_t mantissa = bits & 0x03FFu;
124
125 // NaN or Infinity (f16 exp = 0x1F)
126 if (exp == 0x1Fu) {
127 if (mantissa == 0u) {
128 // ±Inf
129 const uint32_t f32_bits = sign | 0x7F800000u;
130 float result;
131 std::memcpy(&result, &f32_bits, sizeof(result));
132 return result;
133 }
134 // NaN: expand 10-bit f16 fraction to 23-bit f32 fraction by shifting
135 // left 13 bits. The f16 quiet bit (bit 9) maps to the f32 quiet bit
136 // (bit 22), preserving quiet/signaling status and the payload.
137 const uint32_t nan_payload = mantissa << 13;
138 const uint32_t f32_bits = sign | 0x7F800000u | nan_payload;
139 float result;
140 std::memcpy(&result, &f32_bits, sizeof(result));
141 return result;
142 }
143
144 // ±0
145 if (exp == 0u && mantissa == 0u) {
146 float result;
147 std::memcpy(&result, &sign, sizeof(result));
148 return result;
149 }
150
151 // Subnormal f16: normalize into a f32 normal.
152 // f16 subnormals have true exponent -14 and no implicit leading 1.
153 if (exp == 0u) {
154 uint32_t m = mantissa;
155 int32_t e = -14;
156 // Shift left until the implicit leading 1 reaches bit 10.
157 while ((m & 0x0400u) == 0u) {
158 m <<= 1;
159 e -= 1;
160 }
161 m &= 0x03FFu; // strip implicit leading 1
162 const uint32_t exp32 = static_cast<uint32_t>(e + 127);
163 const uint32_t mantissa32 = m << 13;
164 const uint32_t f32_bits = sign | (exp32 << 23) | mantissa32;
165 float result;
166 std::memcpy(&result, &f32_bits, sizeof(result));
167 return result;
168 }
169
170 // Normal f16: remap exponent bias (15 → 127) and zero-extend mantissa
171 // (10 → 23 bits).
172 const uint32_t exp32 = exp - 15u + 127u;
173 const uint32_t mantissa32 = mantissa << 13;
174 const uint32_t f32_bits = sign | (exp32 << 23) | mantissa32;
175 float result;
176 std::memcpy(&result, &f32_bits, sizeof(result));
177 return result;

Callers 15

scalar_to_float32Function · 0.45
scalar_to_float64Function · 0.45
TESTFunction · 0.45
to_stringMethod · 0.45
addMethod · 0.45
subMethod · 0.45
mulMethod · 0.45
divMethod · 0.45
sqrtMethod · 0.45
minMethod · 0.45
maxMethod · 0.45

Calls

no outgoing calls

Tested by 1

TESTFunction · 0.36