@@ -202,18 +202,21 @@ pub fn parseHexFloat(comptime T: type, s: []const u8) !T {
202202 exponent += 1 ;
203203 }
204204
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 ;
213211 mantissa >>= 2 ;
212+ var guardBit = mantissa & 1 == 1 ;
214213 exponent += 2 ;
215214
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 ))) {
217220 // Renormalize, if the exponent overflows we'll catch that below.
218221 mantissa >>= 1 ;
219222 exponent += 1 ;
@@ -338,6 +341,7 @@ test "f128" {
338341 // // Min denormalized value.
339342 .{ .s = "0x1p-16494" , .v = math .f128_true_min },
340343 .{ .s = "-0x1p-16494" , .v = - math .f128_true_min },
344+ .{ .s = "0x1.edcb34a235253948765432134674fp-1" , .v = 0x1.edcb34a235253948765432134674fp-1 },
341345 };
342346
343347 for (cases ) | case | {
0 commit comments