authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-27 23:46:09-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-27 23:46:09-07:00
log3f0062d7a934f7bfcfe80afe31aa1d166edadf54
treebeec902fb943ed4aab04374f7f74562859879192
parent97c61313dab659e4934e0dd31ffa89284151017b
parenteb08fd5f5f386063353c10c88d30d1bf9cbc2714

Merge pull request #100 from MovingtoMars/float_print

basic float printing

3 files changed, 104 insertions(+), 3 deletions(-)

CMakeLists.txt+1
......@@ -125,6 +125,7 @@ set(ZIG_STD_SRC
125125 "${CMAKE_SOURCE_DIR}/std/errno.zig"
126126 "${CMAKE_SOURCE_DIR}/std/rand.zig"
127127 "${CMAKE_SOURCE_DIR}/std/mem.zig"
128 "${CMAKE_SOURCE_DIR}/std/math.zig"
128129)
129130
130131set(C_HEADERS_DEST "lib/zig/include")
std/math.zig created+25
......@@ -0,0 +1,25 @@
1pub fn f64_from_bits(bits: u64) -> f64 {
2 const bits2 = bits;
3 *(&f64)(&bits2)
4}
5
6pub fn f64_to_bits(f: f64) -> u64 {
7 const f2 = f;
8 *(&u64)(&f2)
9}
10
11pub fn f64_get_pos_inf() -> f64 {
12 f64_from_bits(0x7FF0000000000000)
13}
14
15pub fn f64_get_neg_inf() -> f64 {
16 f64_from_bits(0xFFF0000000000000)
17}
18
19pub fn f64_is_nan(f: f64) -> bool {
20 0x7FFFFFFFFFFFFFFF == f64_to_bits(f) // TODO improve to catch all cases
21}
22
23pub fn f64_is_inf(f: f64) -> bool {
24 f == f64_get_neg_inf() || f == f64_get_pos_inf()
25}
std/std.zig+78-3
......@@ -1,5 +1,6 @@
11import "syscall.zig";
22import "errno.zig";
3import "math.zig";
34
45pub const stdin_fileno = 0;
56pub const stdout_fileno = 1;
......@@ -43,6 +44,7 @@ pub error BadFd;
4344
4445const buffer_size = 4 * 1024;
4546const max_u64_base10_digits = 20;
47const max_f64_digits = 65;
4648
4749pub struct OutStream {
4850 fd: isize,
......@@ -92,7 +94,6 @@ pub struct OutStream {
9294 return amt_printed;
9395 }
9496
95
9697 pub fn print_i64(os: &OutStream, x: i64) -> %isize {
9798 if (os.index + max_u64_base10_digits >= os.buffer.len) {
9899 %return os.flush();
......@@ -107,6 +108,19 @@ pub struct OutStream {
107108 return amt_printed;
108109 }
109110
111 pub fn print_f64(os: &OutStream, x: f64) -> %isize {
112 if (os.index + max_f64_digits >= os.buffer.len) {
113 %return os.flush();
114 }
115 const amt_printed = buf_print_f64(os.buffer[os.index...], x);
116 os.index += amt_printed;
117
118 if (!os.buffered) {
119 %return os.flush();
120 }
121
122 return amt_printed;
123 }
110124
111125 pub fn flush(os: &OutStream) -> %void {
112126 const amt_written = write(os.fd, os.buffer.ptr, os.index);
......@@ -199,7 +213,7 @@ fn char_to_digit(c: u8) -> u8 {
199213 }
200214}
201215
202fn buf_print_i64(out_buf: []u8, x: i64) -> isize {
216pub fn buf_print_i64(out_buf: []u8, x: i64) -> isize {
203217 if (x < 0) {
204218 out_buf[0] = '-';
205219 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 {
208222 }
209223}
210224
211fn buf_print_u64(out_buf: []u8, x: u64) -> isize {
225pub fn buf_print_u64(out_buf: []u8, x: u64) -> isize {
212226 var buf: [max_u64_base10_digits]u8 = undefined;
213227 var a = x;
214228 var index = buf.len;
......@@ -229,6 +243,67 @@ fn buf_print_u64(out_buf: []u8, x: u64) -> isize {
229243 return len;
230244}
231245
246pub fn buf_print_f64(out_buf: []u8, x: f64) -> isize {
247 if (x == f64_get_pos_inf()) {
248 const buf2 = "+Inf";
249 @memcpy(&out_buf[0], &buf2[0], buf2.len);
250 return 4;
251 } else if (x == f64_get_neg_inf()) {
252 const buf2 = "-Inf";
253 @memcpy(&out_buf[0], &buf2[0], buf2.len);
254 return 4;
255 } else if (f64_is_nan(x)) {
256 const buf2 = "NaN";
257 @memcpy(&out_buf[0], &buf2[0], buf2.len);
258 return 3;
259 }
260
261 var buf: [max_f64_digits]u8 = undefined;
262
263 var len: isize = 0;
264
265 // 1 sign bit
266 // 11 exponent bits
267 // 52 significand bits (+ 1 implicit always non-zero bit)
268
269 const bits = f64_to_bits(x);
270 if (bits & (1 << 63) != 0) {
271 buf[0] = '-';
272 len += 1;
273 }
274
275 const rexponent: i64 = i64((bits >> 52) & ((1 << 11) - 1));
276 const exponent = rexponent - 1023 - 52;
277 /*%%stdout.printf("exponent: ");
278 %%stdout.print_i64(exponent);
279 %%stdout.printf("\n");*/
280
281 if (rexponent == 0) {
282 buf[len] = '0';
283 len += 1;
284 @memcpy(&out_buf[0], &buf[0], len);
285 return len;
286 }
287
288 const sig = (bits & ((1 << 52) - 1)) | (1 << 52);
289 /*%%stdout.printf("significand: ");
290 %%stdout.print_u64(sig);
291 %%stdout.printf("\n");*/
292
293 len += buf_print_u64(buf[len...], sig);
294 buf[len] = '*';
295 len += 1;
296 buf[len] = '2';
297 len += 1;
298 buf[len] = '^';
299 len += 1;
300 len += buf_print_i64(buf[len...], exponent);
301
302 @memcpy(&out_buf[0], &buf[0], len);
303
304 len
305}
306
232307fn min_isize(x: isize, y: isize) -> isize {
233308 if (x < y) x else y
234309}