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 {
3838 return errolFixed(val, buffer);
3939 }
4040
41
41
4242 // normalize the midpoint
4343
4444 const e = math.frexp(val).exponent;
......@@ -138,7 +138,7 @@ fn tableLowerBound(k: u64) -> usize {
138138
139139 while (j < enum3.len) {
140140 if (enum3[j] < k) {
141 j = 2 * k + 2;
141 j = 2 * j + 2;
142142 } else {
143143 i = j;
144144 j = 2 * j + 1;
......@@ -217,7 +217,7 @@ fn hpMul10(hp: &HP) {
217217
218218 hp.val *= 10.0;
219219 hp.off *= 10.0;
220
220
221221 var off = hp.val;
222222 off -= val * 8.0;
223223 off -= val * 2.0;
......@@ -241,7 +241,7 @@ fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {
241241 var low: u128 = mid - fpeint((fpnext(val) - val) / 2.0);
242242 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) {
245245 high -= 1;
246246 } else {
247247 low -= 1;
......@@ -347,11 +347,11 @@ fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {
347347}
348348
349349fn fpnext(val: f64) -> f64 {
350 return @bitCast(f64, @bitCast(u64, val) + 1);
350 return @bitCast(f64, @bitCast(u64, val) +% 1);
351351}
352352
353353fn fpprev(val: f64) -> f64 {
354 return @bitCast(f64, @bitCast(u64, val) - 1);
354 return @bitCast(f64, @bitCast(u64, val) -% 1);
355355}
356356
357357pub const c_digits_lut = []u8 {
std/fmt/index.zig+27-11
......@@ -244,30 +244,46 @@ pub fn formatBuf(buf: []const u8, width: usize,
244244}
245245
246246pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool {
247 var buffer: [20]u8 = undefined;
248 const float_decimal = errol3(f64(value), buffer[0..]);
249 if (float_decimal.exp != 0) {
250 if (!output(context, float_decimal.digits[0..1]))
251 return false;
252 } else {
253 if (!output(context, "0"))
247 var x = f64(value);
248
249 // Errol doesn't handle these special cases.
250 if (math.isNan(x)) {
251 return output(context, "NaN");
252 }
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, "-"))
254264 return false;
265 x = -x;
255266 }
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;
256272 if (!output(context, "."))
257273 return false;
258274 if (float_decimal.digits.len > 1) {
259 const start = if (float_decimal.exp == 0) usize(0) else usize(1);
260 if (!output(context, float_decimal.digits[start .. math.min(usize(7), float_decimal.digits.len)]))
275 const num_digits = if (@typeOf(value) == f32) { usize(8) } else { usize(17) };
276 if (!output(context, float_decimal.digits[1 .. math.min(num_digits, float_decimal.digits.len)]))
261277 return false;
262278 } else {
263279 if (!output(context, "0"))
264280 return false;
265281 }
266282
267 if (float_decimal.exp != 1 and float_decimal.exp != 0) {
283 if (float_decimal.exp != 1) {
268284 if (!output(context, "e"))
269285 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))
271287 return false;
272288 }
273289 return true;