diff options
| author | scurest <scurest@users.noreply.github.com> | 2017-10-23 15:40:49 -0500 |
|---|---|---|
| committer | scurest <scurest@users.noreply.github.com> | 2017-10-23 15:40:49 -0500 |
| commit | 03a0dfbeca4b31d235097c66c9891d825cf73c15 (patch) | |
| tree | 627ee5acfe6c8ba382e9b53b282d31444a7ed639 /std | |
| parent | c1642355f0b05f182c0b6d81d294d12be79ad0a8 (diff) | |
| download | zig-03a0dfbeca4b31d235097c66c9891d825cf73c15.tar.gz zig-03a0dfbeca4b31d235097c66c9891d825cf73c15.zip | |
Print better floats
Diffstat (limited to 'std')
| -rw-r--r-- | std/fmt/errol/index.zig | 12 | ||||
| -rw-r--r-- | std/fmt/index.zig | 38 |
2 files changed, 33 insertions, 17 deletions
diff --git a/std/fmt/errol/index.zig b/std/fmt/errol/index.zig index ac9f6b0c64..8cf13bca2e 100644 --- a/std/fmt/errol/index.zig +++ b/std/fmt/errol/index.zig @@ -38,7 +38,7 @@ fn errol3u(val: f64, buffer: []u8) -> FloatDecimal { return errolFixed(val, buffer); } - + // normalize the midpoint const e = math.frexp(val).exponent; @@ -138,7 +138,7 @@ fn tableLowerBound(k: u64) -> usize { while (j < enum3.len) { if (enum3[j] < k) { - j = 2 * k + 2; + j = 2 * j + 2; } else { i = j; j = 2 * j + 1; @@ -217,7 +217,7 @@ fn hpMul10(hp: &HP) { hp.val *= 10.0; hp.off *= 10.0; - + var off = hp.val; off -= val * 8.0; off -= val * 2.0; @@ -241,7 +241,7 @@ fn errolInt(val: f64, buffer: []u8) -> FloatDecimal { var low: u128 = mid - fpeint((fpnext(val) - val) / 2.0); var high: u128 = mid + fpeint((val - fpprev(val)) / 2.0); - if (@bitCast(u64, val) & 0x1 != 0) { + if (@bitCast(u64, val) & 0x1 != 0) { high -= 1; } else { low -= 1; @@ -347,11 +347,11 @@ fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal { } fn fpnext(val: f64) -> f64 { - return @bitCast(f64, @bitCast(u64, val) + 1); + return @bitCast(f64, @bitCast(u64, val) +% 1); } fn fpprev(val: f64) -> f64 { - return @bitCast(f64, @bitCast(u64, val) - 1); + return @bitCast(f64, @bitCast(u64, val) -% 1); } pub const c_digits_lut = []u8 { diff --git a/std/fmt/index.zig b/std/fmt/index.zig index b378afa1b0..85688b361d 100644 --- a/std/fmt/index.zig +++ b/std/fmt/index.zig @@ -244,30 +244,46 @@ pub fn formatBuf(buf: []const u8, width: usize, } pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool { - var buffer: [20]u8 = undefined; - const float_decimal = errol3(f64(value), buffer[0..]); - if (float_decimal.exp != 0) { - if (!output(context, float_decimal.digits[0..1])) - return false; - } else { - if (!output(context, "0")) + var x = f64(value); + + // Errol doesn't handle these special cases. + if (math.isNan(x)) { + return output(context, "NaN"); + } + if (math.isPositiveInf(x)) { + return output(context, "Infinity"); + } + if (math.isNegativeInf(x)) { + return output(context, "-Infinity"); + } + if (x == 0.0) { + return output(context, "0.0"); + } + if (x < 0.0) { + if (!output(context, "-")) return false; + x = -x; } + + var buffer: [32]u8 = undefined; + const float_decimal = errol3(x, buffer[0..]); + if (!output(context, float_decimal.digits[0..1])) + return false; if (!output(context, ".")) return false; if (float_decimal.digits.len > 1) { - const start = if (float_decimal.exp == 0) usize(0) else usize(1); - if (!output(context, float_decimal.digits[start .. math.min(usize(7), float_decimal.digits.len)])) + const num_digits = if (@typeOf(value) == f32) { usize(8) } else { usize(17) }; + if (!output(context, float_decimal.digits[1 .. math.min(num_digits, float_decimal.digits.len)])) return false; } else { if (!output(context, "0")) return false; } - if (float_decimal.exp != 1 and float_decimal.exp != 0) { + if (float_decimal.exp != 1) { if (!output(context, "e")) return false; - if (!formatInt(float_decimal.exp, 10, false, 0, context, output)) + if (!formatInt(float_decimal.exp - 1, 10, false, 0, context, output)) return false; } return true; |
