aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-01-31 22:59:49 -0500
committerGitHub <noreply@github.com>2022-01-31 22:59:49 -0500
commitd3e40b0d8085ec82e6e5b33f2010de6cb9779ce5 (patch)
tree998df07db358b117250000eb539a08a021af3873 /lib
parent627cf6ce482349c172150d058660f7a1646c2aac (diff)
parentc46f7588cea98c48e6c7f637e13536378027e260 (diff)
downloadzig-d3e40b0d8085ec82e6e5b33f2010de6cb9779ce5.tar.gz
zig-d3e40b0d8085ec82e6e5b33f2010de6cb9779ce5.zip
Merge pull request #10743 from m-radomski/master
std: correct rounding in parse_hex_float.zig
Diffstat (limited to 'lib')
-rw-r--r--lib/std/fmt/parse_hex_float.zig20
1 files changed, 11 insertions, 9 deletions
diff --git a/lib/std/fmt/parse_hex_float.zig b/lib/std/fmt/parse_hex_float.zig
index 45a289fdd2..83c798ab96 100644
--- a/lib/std/fmt/parse_hex_float.zig
+++ b/lib/std/fmt/parse_hex_float.zig
@@ -202,18 +202,19 @@ pub fn parseHexFloat(comptime T: type, s: []const u8) !T {
exponent += 1;
}
- // There are two cases to handle:
- // - We've truncated more than 0.5ULP (R=S=1), increase the mantissa.
- // - We've truncated exactly 0.5ULP (R=1 S=0), increase the mantissa if the
- // result is odd (G=1).
- // The two checks can be neatly folded as follows.
- mantissa |= @boolToInt(mantissa & 0b100 != 0);
- mantissa += 1;
-
+ // Whenever the guard bit is one (G=1) and:
+ // - we've truncated more than 0.5ULP (R=S=1)
+ // - we've truncated exactly 0.5ULP (R=1 S=0)
+ // Were are going to increase the mantissa (round up)
+ const guard_bit_and_half_or_more = (mantissa & 0b110) == 0b110;
mantissa >>= 2;
exponent += 2;
- if (mantissa & (1 << (mantissa_bits + 1)) != 0) {
+ if (guard_bit_and_half_or_more) {
+ mantissa += 1;
+ }
+
+ if (mantissa == (1 << (mantissa_bits + 1))) {
// Renormalize, if the exponent overflows we'll catch that below.
mantissa >>= 1;
exponent += 1;
@@ -338,6 +339,7 @@ test "f128" {
// // Min denormalized value.
.{ .s = "0x1p-16494", .v = math.f128_true_min },
.{ .s = "-0x1p-16494", .v = -math.f128_true_min },
+ .{ .s = "0x1.edcb34a235253948765432134674fp-1", .v = 0x1.edcb34a235253948765432134674fp-1 },
};
for (cases) |case| {