Skip to content

Improved printing for floats #563

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 9 additions & 13 deletions std/fmt/errol/index.zig
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ pub fn errol3(value: f64, buffer: []u8) -> FloatDecimal {
fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {
// check if in integer or fixed range

if (val >= 9.007199254740992e15 and val < 3.40282366920938e+38) {
if (val > 9.007199254740992e15 and val < 3.40282366920938e+38) {
return errolInt(val, buffer);
} else if (val >= 16.0 and val < 9.007199254740992e15) {
return errolFixed(val, buffer);
}


// normalize the midpoint

const e = math.frexp(val).exponent;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -235,13 +235,13 @@ fn hpMul10(hp: &HP) {
fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {
const pow19 = u128(1e19);

assert((val >= 9.007199254740992e15) and val < (3.40282366920938e38));
assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));

var mid = u128(val);
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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -510,10 +510,6 @@ fn u64toa(value_param: u64, buffer: []u8) -> usize {
buf_index += 1;
buffer[buf_index] = c_digits_lut[d8];
buf_index += 1;
buffer[buf_index] = c_digits_lut[d8];
buf_index += 1;
buffer[buf_index] = c_digits_lut[d8];
buf_index += 1;
buffer[buf_index] = c_digits_lut[d8 + 1];
buf_index += 1;
} else {
Expand Down Expand Up @@ -613,7 +609,7 @@ fn fpeint(from: f64) -> u128 {
const bits = @bitCast(u64, from);
assert((bits & ((1 << 52) - 1)) == 0);

return u64(1) << u6(((bits >> 52) - 1023));
return u128(1) << @truncate(u7, (bits >> 52) -% 1023);
}


Expand Down
39 changes: 28 additions & 11 deletions std/fmt/index.zig
Original file line number Diff line number Diff line change
Expand Up @@ -244,30 +244,47 @@ 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.signbit(x)) {
if (!output(context, "-"))
return false;
x = -x;
}
if (math.isPositiveInf(x)) {
return output(context, "Infinity");
}
if (x == 0.0) {
return output(context, "0.0");
}

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) {
math.min(usize(9), float_decimal.digits.len)
} else {
float_decimal.digits.len
};
if (!output(context, float_decimal.digits[1 .. num_digits]))
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;
Expand Down