@@ -202,18 +202,21 @@ pub fn parseHexFloat(comptime T: type, s: []const u8) !T {
202
202
exponent += 1 ;
203
203
}
204
204
205
- // There are two cases to handle:
206
- // - We've truncated more than 0.5ULP (R=S=1), increase the mantissa.
207
- // - We've truncated exactly 0.5ULP (R=1 S=0), increase the mantissa if the
208
- // result is odd (G=1).
209
- // The two checks can be neatly folded as follows.
210
- mantissa |= @boolToInt (mantissa & 0b100 != 0 );
211
- mantissa += 1 ;
212
-
205
+ // Whenever the guard bit is one (G=1) and:
206
+ // - we've truncated more than 0.5ULP (R=S=1)
207
+ // - we've truncated exactly 0.5ULP (R=1 S=0)
208
+ // Were are going to increase the mantissa (round up)
209
+ var exactly_half = (mantissa & 0b11 ) == 0b10 ;
210
+ var more_than_half = (mantissa & 0b11 ) == 0b11 ;
213
211
mantissa >>= 2 ;
212
+ var guardBit = mantissa & 1 == 1 ;
214
213
exponent += 2 ;
215
214
216
- if (mantissa & (1 << (mantissa_bits + 1 )) != 0 ) {
215
+ if (guardBit and (exactly_half or more_than_half )) {
216
+ mantissa += 1 ;
217
+ }
218
+
219
+ if (mantissa == (1 << (mantissa_bits + 1 ))) {
217
220
// Renormalize, if the exponent overflows we'll catch that below.
218
221
mantissa >>= 1 ;
219
222
exponent += 1 ;
@@ -338,6 +341,7 @@ test "f128" {
338
341
// // Min denormalized value.
339
342
.{ .s = "0x1p-16494" , .v = math .f128_true_min },
340
343
.{ .s = "-0x1p-16494" , .v = - math .f128_true_min },
344
+ .{ .s = "0x1.edcb34a235253948765432134674fp-1" , .v = 0x1.edcb34a235253948765432134674fp-1 },
341
345
};
342
346
343
347
for (cases ) | case | {
0 commit comments