Commit 03a0dfbeca

scurest <scurest@users.noreply.github.com>
2017-10-23 22:40:49
Print better floats
1 parent c164235
Changed files (2)
std
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 {
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;