authorgravatar for liam@bumblebee.net.nzMovingtoMars <liam@bumblebee.net.nz> 2016-01-28 19:28:43+13:00
committergravatar for liam@bumblebee.net.nzMovingtoMars <liam@bumblebee.net.nz> 2016-01-28 19:28:43+13:00
logdc084128954b99f93a0d974c3e5ed8347e9f1e8a
tree4886afff1524b74bbe90fc263d61688eac35df1c
parente3cc0c25718e8ff580eabce35ba845e968c74e1a

basic float printing


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

CMakeLists.txt+1
...@@ -124,6 +124,7 @@ set(ZIG_STD_SRC...@@ -124,6 +124,7 @@ set(ZIG_STD_SRC
124 "${CMAKE_SOURCE_DIR}/std/errno.zig"124 "${CMAKE_SOURCE_DIR}/std/errno.zig"
125 "${CMAKE_SOURCE_DIR}/std/rand.zig"125 "${CMAKE_SOURCE_DIR}/std/rand.zig"
126 "${CMAKE_SOURCE_DIR}/std/mem.zig"126 "${CMAKE_SOURCE_DIR}/std/mem.zig"
127 "${CMAKE_SOURCE_DIR}/std/math.zig"
127)128)
128129
129set(C_HEADERS_DEST "lib/zig/include")130set(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+79-3
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1import "syscall.zig";1import "syscall.zig";
2import "errno.zig";2import "errno.zig";
3import "math.zig";
34
4pub const stdin_fileno = 0;5pub const stdin_fileno = 0;
5pub const stdout_fileno = 1;6pub const stdout_fileno = 1;
...@@ -43,6 +44,7 @@ pub error BadFd;...@@ -43,6 +44,7 @@ pub error BadFd;
4344
44const buffer_size = 4 * 1024;45const buffer_size = 4 * 1024;
45const max_u64_base10_digits = 20;46const max_u64_base10_digits = 20;
47const max_f64_digits = 65;
4648
47pub struct OutStream {49pub struct OutStream {
48 fd: isize,50 fd: isize,
...@@ -92,7 +94,6 @@ pub struct OutStream {...@@ -92,7 +94,6 @@ pub struct OutStream {
92 return amt_printed;94 return amt_printed;
93 }95 }
9496
95
96 pub fn print_i64(os: &OutStream, x: i64) -> %isize {97 pub fn print_i64(os: &OutStream, x: i64) -> %isize {
97 if (os.index + max_u64_base10_digits >= os.buffer.len) {98 if (os.index + max_u64_base10_digits >= os.buffer.len) {
98 %return os.flush();99 %return os.flush();
...@@ -107,6 +108,19 @@ pub struct OutStream {...@@ -107,6 +108,19 @@ pub struct OutStream {
107 return amt_printed;108 return amt_printed;
108 }109 }
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
111 pub fn flush(os: &OutStream) -> %void {125 pub fn flush(os: &OutStream) -> %void {
112 const amt_written = write(os.fd, os.buffer.ptr, os.index);126 const amt_written = write(os.fd, os.buffer.ptr, os.index);
...@@ -199,7 +213,7 @@ fn char_to_digit(c: u8) -> u8 {...@@ -199,7 +213,7 @@ fn char_to_digit(c: u8) -> u8 {
199 }213 }
200}214}
201215
202fn buf_print_i64(out_buf: []u8, x: i64) -> isize {216pub fn buf_print_i64(out_buf: []u8, x: i64) -> isize {
203 if (x < 0) {217 if (x < 0) {
204 out_buf[0] = '-';218 out_buf[0] = '-';
205 return 1 + buf_print_u64(out_buf[1...], u64(-(x + 1)) + 1);219 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 {...@@ -208,7 +222,7 @@ fn buf_print_i64(out_buf: []u8, x: i64) -> isize {
208 }222 }
209}223}
210224
211fn buf_print_u64(out_buf: []u8, x: u64) -> isize {225pub fn buf_print_u64(out_buf: []u8, x: u64) -> isize {
212 var buf: [max_u64_base10_digits]u8 = undefined;226 var buf: [max_u64_base10_digits]u8 = undefined;
213 var a = x;227 var a = x;
214 var index = buf.len;228 var index = buf.len;
...@@ -229,6 +243,68 @@ fn buf_print_u64(out_buf: []u8, x: u64) -> isize {...@@ -229,6 +243,68 @@ fn buf_print_u64(out_buf: []u8, x: u64) -> isize {
229 return len;243 return len;
230}244}
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], 4);
250 return 4;
251 } else if (x == f64_get_neg_inf()) {
252 const buf2 = "-Inf";
253 @memcpy(&out_buf[0], &buf2[0], 4);
254 return 4;
255 } else if (f64_is_nan(x)) {
256 const buf2 = "NaN";
257 @memcpy(&out_buf[0], &buf2[0], 3);
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 %%stdout.printf("neg\n");
272 buf[0] = '-';
273 len += 1;
274 }
275
276 const rexponent: i64 = i64((bits >> 52) & ((1 << 11) - 1));
277 const exponent = rexponent - 1023 - 52;
278 /*%%stdout.printf("exponent: ");
279 %%stdout.print_i64(exponent);
280 %%stdout.printf("\n");*/
281
282 if (rexponent == 0) {
283 buf[len] = '0';
284 len += 1;
285 @memcpy(&out_buf[0], &buf[0], len);
286 return len;
287 }
288
289 const sig = (bits & ((1 << 52) - 1)) | (1 << 52);
290 /*%%stdout.printf("significand: ");
291 %%stdout.print_u64(sig);
292 %%stdout.printf("\n");*/
293
294 len += buf_print_u64(buf[len...], sig);
295 buf[len] = '*';
296 len += 1;
297 buf[len] = '2';
298 len += 1;
299 buf[len] = '^';
300 len += 1;
301 len += buf_print_i64(buf[len...], exponent);
302
303 @memcpy(&out_buf[0], &buf[0], len);
304
305 len
306}
307
232fn min_isize(x: isize, y: isize) -> isize {308fn min_isize(x: isize, y: isize) -> isize {
233 if (x < y) x else y309 if (x < y) x else y
234}310}