authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-24 21:44:49-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-24 21:44:49-04:00
log1e784839f1b6ac116f7cae35fa4a8069902283b6
treec54d2cd1e058c85aaf3d2abe21ca710256ef0507
parent1828f8eb8e1514578ed2da8d58536903f94b7ed0
parent262b7428cfad88de9d328773cc4bae6151b8a030

Merge branch 'float-printing' of https://github.com/scurest/zig into better-float-printing


2 files changed, 37 insertions(+), 24 deletions(-)

std/fmt/errol/index.zig+9-13
......@@ -32,13 +32,13 @@ pub fn errol3(value: f64, buffer: []u8) -> FloatDecimal {
3232fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {
3333 // check if in integer or fixed range
3434
35 if (val >= 9.007199254740992e15 and val < 3.40282366920938e+38) {
35 if (val > 9.007199254740992e15 and val < 3.40282366920938e+38) {
3636 return errolInt(val, buffer);
3737 } else if (val >= 16.0 and val < 9.007199254740992e15) {
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;
......@@ -235,13 +235,13 @@ fn hpMul10(hp: &HP) {
235235fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {
236236 const pow19 = u128(1e19);
237237
238 assert((val >= 9.007199254740992e15) and val < (3.40282366920938e38));
238 assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));
239239
240240 var mid = u128(val);
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 {
......@@ -510,10 +510,6 @@ fn u64toa(value_param: u64, buffer: []u8) -> usize {
510510 buf_index += 1;
511511 buffer[buf_index] = c_digits_lut[d8];
512512 buf_index += 1;
513 buffer[buf_index] = c_digits_lut[d8];
514 buf_index += 1;
515 buffer[buf_index] = c_digits_lut[d8];
516 buf_index += 1;
517513 buffer[buf_index] = c_digits_lut[d8 + 1];
518514 buf_index += 1;
519515 } else {
......@@ -613,7 +609,7 @@ fn fpeint(from: f64) -> u128 {
613609 const bits = @bitCast(u64, from);
614610 assert((bits & ((1 << 52) - 1)) == 0);
615611
616 return u64(1) << u6(((bits >> 52) - 1023));
612 return u128(1) << @truncate(u7, (bits >> 52) -% 1023);
617613}
618614
619615
std/fmt/index.zig+28-11
......@@ -244,30 +244,47 @@ 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.signbit(x)) {
254 if (!output(context, "-"))
254255 return false;
256 x = -x;
255257 }
258 if (math.isPositiveInf(x)) {
259 return output(context, "Infinity");
260 }
261 if (x == 0.0) {
262 return output(context, "0.0");
263 }
264
265 var buffer: [32]u8 = undefined;
266 const float_decimal = errol3(x, buffer[0..]);
267 if (!output(context, float_decimal.digits[0..1]))
268 return false;
256269 if (!output(context, "."))
257270 return false;
258271 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)]))
272 const num_digits = if (@typeOf(value) == f32) {
273 math.min(usize(9), float_decimal.digits.len)
274 } else {
275 float_decimal.digits.len
276 };
277 if (!output(context, float_decimal.digits[1 .. num_digits]))
261278 return false;
262279 } else {
263280 if (!output(context, "0"))
264281 return false;
265282 }
266283
267 if (float_decimal.exp != 1 and float_decimal.exp != 0) {
284 if (float_decimal.exp != 1) {
268285 if (!output(context, "e"))
269286 return false;
270 if (!formatInt(float_decimal.exp, 10, false, 0, context, output))
287 if (!formatInt(float_decimal.exp - 1, 10, false, 0, context, output))
271288 return false;
272289 }
273290 return true;