authorgravatar for scurest@users.noreply.github.comscurest <scurest@users.noreply.github.com> 2017-10-23 15:40:49-05:00
committergravatar for scurest@users.noreply.github.comscurest <scurest@users.noreply.github.com> 2017-10-23 15:40:49-05:00
log03a0dfbeca4b31d235097c66c9891d825cf73c15
tree627ee5acfe6c8ba382e9b53b282d31444a7ed639
parentc1642355f0b05f182c0b6d81d294d12be79ad0a8

Print better floats


2 files changed, 33 insertions(+), 17 deletions(-)

std/fmt/errol/index.zig+6-6
...@@ -38,7 +38,7 @@ fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {...@@ -38,7 +38,7 @@ fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {
38 return errolFixed(val, buffer);38 return errolFixed(val, buffer);
39 }39 }
4040
41 41
42 // normalize the midpoint42 // normalize the midpoint
4343
44 const e = math.frexp(val).exponent;44 const e = math.frexp(val).exponent;
...@@ -138,7 +138,7 @@ fn tableLowerBound(k: u64) -> usize {...@@ -138,7 +138,7 @@ fn tableLowerBound(k: u64) -> usize {
138138
139 while (j < enum3.len) {139 while (j < enum3.len) {
140 if (enum3[j] < k) {140 if (enum3[j] < k) {
141 j = 2 * k + 2;141 j = 2 * j + 2;
142 } else {142 } else {
143 i = j;143 i = j;
144 j = 2 * j + 1;144 j = 2 * j + 1;
...@@ -217,7 +217,7 @@ fn hpMul10(hp: &HP) {...@@ -217,7 +217,7 @@ fn hpMul10(hp: &HP) {
217217
218 hp.val *= 10.0;218 hp.val *= 10.0;
219 hp.off *= 10.0;219 hp.off *= 10.0;
220 220
221 var off = hp.val;221 var off = hp.val;
222 off -= val * 8.0;222 off -= val * 8.0;
223 off -= val * 2.0;223 off -= val * 2.0;
...@@ -241,7 +241,7 @@ fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {...@@ -241,7 +241,7 @@ fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {
241 var low: u128 = mid - fpeint((fpnext(val) - val) / 2.0);241 var low: u128 = mid - fpeint((fpnext(val) - val) / 2.0);
242 var high: u128 = mid + fpeint((val - fpprev(val)) / 2.0);242 var high: u128 = mid + fpeint((val - fpprev(val)) / 2.0);
243243
244 if (@bitCast(u64, val) & 0x1 != 0) { 244 if (@bitCast(u64, val) & 0x1 != 0) {
245 high -= 1;245 high -= 1;
246 } else {246 } else {
247 low -= 1;247 low -= 1;
...@@ -347,11 +347,11 @@ fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {...@@ -347,11 +347,11 @@ fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {
347}347}
348348
349fn fpnext(val: f64) -> f64 {349fn fpnext(val: f64) -> f64 {
350 return @bitCast(f64, @bitCast(u64, val) + 1);350 return @bitCast(f64, @bitCast(u64, val) +% 1);
351}351}
352352
353fn fpprev(val: f64) -> f64 {353fn fpprev(val: f64) -> f64 {
354 return @bitCast(f64, @bitCast(u64, val) - 1);354 return @bitCast(f64, @bitCast(u64, val) -% 1);
355}355}
356356
357pub const c_digits_lut = []u8 {357pub const c_digits_lut = []u8 {
std/fmt/index.zig+27-11
...@@ -244,30 +244,46 @@ pub fn formatBuf(buf: []const u8, width: usize,...@@ -244,30 +244,46 @@ pub fn formatBuf(buf: []const u8, width: usize,
244}244}
245245
246pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool {246pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool {
247 var buffer: [20]u8 = undefined;247 var x = f64(value);
248 const float_decimal = errol3(f64(value), buffer[0..]);248
249 if (float_decimal.exp != 0) {249 // Errol doesn't handle these special cases.
250 if (!output(context, float_decimal.digits[0..1]))250 if (math.isNan(x)) {
251 return false;251 return output(context, "NaN");
252 } else {252 }
253 if (!output(context, "0"))253 if (math.isPositiveInf(x)) {
254 return output(context, "Infinity");
255 }
256 if (math.isNegativeInf(x)) {
257 return output(context, "-Infinity");
258 }
259 if (x == 0.0) {
260 return output(context, "0.0");
261 }
262 if (x < 0.0) {
263 if (!output(context, "-"))
254 return false;264 return false;
265 x = -x;
255 }266 }
267
268 var buffer: [32]u8 = undefined;
269 const float_decimal = errol3(x, buffer[0..]);
270 if (!output(context, float_decimal.digits[0..1]))
271 return false;
256 if (!output(context, "."))272 if (!output(context, "."))
257 return false;273 return false;
258 if (float_decimal.digits.len > 1) {274 if (float_decimal.digits.len > 1) {
259 const start = if (float_decimal.exp == 0) usize(0) else usize(1);275 const num_digits = if (@typeOf(value) == f32) { usize(8) } else { usize(17) };
260 if (!output(context, float_decimal.digits[start .. math.min(usize(7), float_decimal.digits.len)]))276 if (!output(context, float_decimal.digits[1 .. math.min(num_digits, float_decimal.digits.len)]))
261 return false;277 return false;
262 } else {278 } else {
263 if (!output(context, "0"))279 if (!output(context, "0"))
264 return false;280 return false;
265 }281 }
266282
267 if (float_decimal.exp != 1 and float_decimal.exp != 0) {283 if (float_decimal.exp != 1) {
268 if (!output(context, "e"))284 if (!output(context, "e"))
269 return false;285 return false;
270 if (!formatInt(float_decimal.exp, 10, false, 0, context, output))286 if (!formatInt(float_decimal.exp - 1, 10, false, 0, context, output))
271 return false;287 return false;
272 }288 }
273 return true;289 return true;