aboutsummaryrefslogtreecommitdiff
path: root/std/std.zig
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-01-27 23:46:09 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-01-27 23:46:09 -0700
commit3f0062d7a934f7bfcfe80afe31aa1d166edadf54 (patch)
treebeec902fb943ed4aab04374f7f74562859879192 /std/std.zig
parent97c61313dab659e4934e0dd31ffa89284151017b (diff)
parenteb08fd5f5f386063353c10c88d30d1bf9cbc2714 (diff)
downloadzig-3f0062d7a934f7bfcfe80afe31aa1d166edadf54.tar.gz
zig-3f0062d7a934f7bfcfe80afe31aa1d166edadf54.zip
Merge pull request #100 from MovingtoMars/float_print
basic float printing
Diffstat (limited to 'std/std.zig')
-rw-r--r--std/std.zig81
1 files changed, 78 insertions, 3 deletions
diff --git a/std/std.zig b/std/std.zig
index 19aafbbb40..ecf5db6018 100644
--- a/std/std.zig
+++ b/std/std.zig
@@ -1,5 +1,6 @@
import "syscall.zig";
import "errno.zig";
+import "math.zig";
pub const stdin_fileno = 0;
pub const stdout_fileno = 1;
@@ -43,6 +44,7 @@ pub error BadFd;
const buffer_size = 4 * 1024;
const max_u64_base10_digits = 20;
+const max_f64_digits = 65;
pub struct OutStream {
fd: isize,
@@ -92,7 +94,6 @@ pub struct OutStream {
return amt_printed;
}
-
pub fn print_i64(os: &OutStream, x: i64) -> %isize {
if (os.index + max_u64_base10_digits >= os.buffer.len) {
%return os.flush();
@@ -107,6 +108,19 @@ pub struct OutStream {
return amt_printed;
}
+ pub fn print_f64(os: &OutStream, x: f64) -> %isize {
+ if (os.index + max_f64_digits >= os.buffer.len) {
+ %return os.flush();
+ }
+ const amt_printed = buf_print_f64(os.buffer[os.index...], x);
+ os.index += amt_printed;
+
+ if (!os.buffered) {
+ %return os.flush();
+ }
+
+ return amt_printed;
+ }
pub fn flush(os: &OutStream) -> %void {
const amt_written = write(os.fd, os.buffer.ptr, os.index);
@@ -199,7 +213,7 @@ fn char_to_digit(c: u8) -> u8 {
}
}
-fn buf_print_i64(out_buf: []u8, x: i64) -> isize {
+pub fn buf_print_i64(out_buf: []u8, x: i64) -> isize {
if (x < 0) {
out_buf[0] = '-';
return 1 + buf_print_u64(out_buf[1...], u64(-(x + 1)) + 1);
@@ -208,7 +222,7 @@ fn buf_print_i64(out_buf: []u8, x: i64) -> isize {
}
}
-fn buf_print_u64(out_buf: []u8, x: u64) -> isize {
+pub fn buf_print_u64(out_buf: []u8, x: u64) -> isize {
var buf: [max_u64_base10_digits]u8 = undefined;
var a = x;
var index = buf.len;
@@ -229,6 +243,67 @@ fn buf_print_u64(out_buf: []u8, x: u64) -> isize {
return len;
}
+pub fn buf_print_f64(out_buf: []u8, x: f64) -> isize {
+ if (x == f64_get_pos_inf()) {
+ const buf2 = "+Inf";
+ @memcpy(&out_buf[0], &buf2[0], buf2.len);
+ return 4;
+ } else if (x == f64_get_neg_inf()) {
+ const buf2 = "-Inf";
+ @memcpy(&out_buf[0], &buf2[0], buf2.len);
+ return 4;
+ } else if (f64_is_nan(x)) {
+ const buf2 = "NaN";
+ @memcpy(&out_buf[0], &buf2[0], buf2.len);
+ return 3;
+ }
+
+ var buf: [max_f64_digits]u8 = undefined;
+
+ var len: isize = 0;
+
+ // 1 sign bit
+ // 11 exponent bits
+ // 52 significand bits (+ 1 implicit always non-zero bit)
+
+ const bits = f64_to_bits(x);
+ if (bits & (1 << 63) != 0) {
+ buf[0] = '-';
+ len += 1;
+ }
+
+ const rexponent: i64 = i64((bits >> 52) & ((1 << 11) - 1));
+ const exponent = rexponent - 1023 - 52;
+ /*%%stdout.printf("exponent: ");
+ %%stdout.print_i64(exponent);
+ %%stdout.printf("\n");*/
+
+ if (rexponent == 0) {
+ buf[len] = '0';
+ len += 1;
+ @memcpy(&out_buf[0], &buf[0], len);
+ return len;
+ }
+
+ const sig = (bits & ((1 << 52) - 1)) | (1 << 52);
+ /*%%stdout.printf("significand: ");
+ %%stdout.print_u64(sig);
+ %%stdout.printf("\n");*/
+
+ len += buf_print_u64(buf[len...], sig);
+ buf[len] = '*';
+ len += 1;
+ buf[len] = '2';
+ len += 1;
+ buf[len] = '^';
+ len += 1;
+ len += buf_print_i64(buf[len...], exponent);
+
+ @memcpy(&out_buf[0], &buf[0], len);
+
+ len
+}
+
fn min_isize(x: isize, y: isize) -> isize {
if (x < y) x else y
}