authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-17 22:52:12-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-17 22:52:12-04:00
log1b5d61bee9a50a6dc0941c3512ffa7e0abbf9c52
treec5ea3d45f894c4cdab8e1fea65ea4675eda85590
parent2173e1f457f49990313e1ad038187af8a78205ab

fix bitCast for big integers

and make bigfloat use __float128

6 files changed, 66 insertions(+), 10 deletions(-)

src/bigfloat.cpp+11-4
...@@ -11,7 +11,7 @@...@@ -11,7 +11,7 @@
11#include <math.h>11#include <math.h>
12#include <errno.h>12#include <errno.h>
1313
14void bigfloat_init_float(BigFloat *dest, long double x) {14void bigfloat_init_float(BigFloat *dest, __float128 x) {
15 dest->value = x;15 dest->value = x;
16}16}
1717
...@@ -24,13 +24,13 @@ void bigfloat_init_bigint(BigFloat *dest, const BigInt *op) {...@@ -24,13 +24,13 @@ void bigfloat_init_bigint(BigFloat *dest, const BigInt *op) {
24 if (op->digit_count == 0)24 if (op->digit_count == 0)
25 return;25 return;
2626
27 long double base = (long double)UINT64_MAX;27 __float128 base = (__float128)UINT64_MAX;
28 const uint64_t *digits = bigint_ptr(op);28 const uint64_t *digits = bigint_ptr(op);
2929
30 for (size_t i = op->digit_count - 1;;) {30 for (size_t i = op->digit_count - 1;;) {
31 uint64_t digit = digits[i];31 uint64_t digit = digits[i];
32 dest->value *= base;32 dest->value *= base;
33 dest->value += (long double)digit;33 dest->value += (__float128)digit;
3434
35 if (i == 0) {35 if (i == 0) {
36 if (op->is_negative) {36 if (op->is_negative) {
...@@ -96,7 +96,7 @@ void bigfloat_mod(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {...@@ -96,7 +96,7 @@ void bigfloat_mod(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
96}96}
9797
98void bigfloat_write_buf(Buf *buf, const BigFloat *op) {98void bigfloat_write_buf(Buf *buf, const BigFloat *op) {
99 buf_appendf(buf, "%Lf", op->value);99 buf_appendf(buf, "%Lf", (long double)op->value);
100}100}
101101
102Cmp bigfloat_cmp(const BigFloat *op1, const BigFloat *op2) {102Cmp bigfloat_cmp(const BigFloat *op1, const BigFloat *op2) {
...@@ -117,6 +117,9 @@ void bigfloat_write_ieee597(const BigFloat *op, uint8_t *buf, size_t bit_count,...@@ -117,6 +117,9 @@ void bigfloat_write_ieee597(const BigFloat *op, uint8_t *buf, size_t bit_count,
117 } else if (bit_count == 64) {117 } else if (bit_count == 64) {
118 double f64 = op->value;118 double f64 = op->value;
119 memcpy(buf, &f64, 8);119 memcpy(buf, &f64, 8);
120 } else if (bit_count == 128) {
121 __float128 f128 = op->value;
122 memcpy(buf, &f128, 16);
120 } else {123 } else {
121 zig_unreachable();124 zig_unreachable();
122 }125 }
...@@ -132,6 +135,10 @@ void bigfloat_read_ieee597(BigFloat *dest, const uint8_t *buf, size_t bit_count,...@@ -132,6 +135,10 @@ void bigfloat_read_ieee597(BigFloat *dest, const uint8_t *buf, size_t bit_count,
132 double f64;135 double f64;
133 memcpy(&f64, buf, 8);136 memcpy(&f64, buf, 8);
134 dest->value = f64;137 dest->value = f64;
138 } else if (bit_count == 128) {
139 __float128 f128;
140 memcpy(&f128, buf, 16);
141 dest->value = f128;
135 } else {142 } else {
136 zig_unreachable();143 zig_unreachable();
137 }144 }
src/bigfloat.hpp+2-2
...@@ -14,12 +14,12 @@...@@ -14,12 +14,12 @@
14#include <stddef.h>14#include <stddef.h>
1515
16struct BigFloat {16struct BigFloat {
17 long double value;17 __float128 value;
18};18};
1919
20struct Buf;20struct Buf;
2121
22void bigfloat_init_float(BigFloat *dest, long double x);22void bigfloat_init_float(BigFloat *dest, __float128 x);
23void bigfloat_init_bigfloat(BigFloat *dest, const BigFloat *x);23void bigfloat_init_bigfloat(BigFloat *dest, const BigFloat *x);
24void bigfloat_init_bigint(BigFloat *dest, const BigInt *op);24void bigfloat_init_bigint(BigFloat *dest, const BigInt *op);
25int bigfloat_init_buf_base10(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len);25int bigfloat_init_buf_base10(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len);
src/bigint.cpp+5-4
...@@ -220,6 +220,7 @@ void bigint_write_twos_complement(const BigInt *big_int, uint8_t *buf, size_t bi...@@ -220,6 +220,7 @@ void bigint_write_twos_complement(const BigInt *big_int, uint8_t *buf, size_t bi
220 const uint64_t *twos_comp_digits = bigint_ptr(&twos_comp);220 const uint64_t *twos_comp_digits = bigint_ptr(&twos_comp);
221221
222 size_t bits_in_last_digit = bit_count % 64;222 size_t bits_in_last_digit = bit_count % 64;
223 if (bits_in_last_digit == 0) bits_in_last_digit = 64;
223 size_t bytes_in_last_digit = (bits_in_last_digit + 7) / 8;224 size_t bytes_in_last_digit = (bits_in_last_digit + 7) / 8;
224 size_t unwritten_byte_count = 8 - bytes_in_last_digit;225 size_t unwritten_byte_count = 8 - bytes_in_last_digit;
225226
...@@ -258,13 +259,13 @@ void bigint_write_twos_complement(const BigInt *big_int, uint8_t *buf, size_t bi...@@ -258,13 +259,13 @@ void bigint_write_twos_complement(const BigInt *big_int, uint8_t *buf, size_t bi
258 for (size_t digit_index = 0; digit_index < digit_count; digit_index += 1) {259 for (size_t digit_index = 0; digit_index < digit_count; digit_index += 1) {
259 uint64_t x = (digit_index < twos_comp.digit_count) ? twos_comp_digits[digit_index] : 0;260 uint64_t x = (digit_index < twos_comp.digit_count) ? twos_comp_digits[digit_index] : 0;
260261
261 for (size_t byte_index = 0; byte_index < 8; byte_index += 1) {262 for (size_t byte_index = 0;
263 byte_index < 8 && (digit_index + 1 < digit_count || byte_index < bytes_in_last_digit);
264 byte_index += 1)
265 {
262 uint8_t byte = x & 0xff;266 uint8_t byte = x & 0xff;
263 buf[buf_index] = byte;267 buf[buf_index] = byte;
264 buf_index += 1;268 buf_index += 1;
265 if (buf_index >= unwritten_byte_count) {
266 break;
267 }
268 x >>= 8;269 x >>= 8;
269 }270 }
270 }271 }
std/special/compiler_rt/README.md+9
...@@ -13,3 +13,12 @@ Any bugs should be solved by trying to duplicate the bug upstream....@@ -13,3 +13,12 @@ Any bugs should be solved by trying to duplicate the bug upstream.
13 * If the bug only exists in Zig, something went wrong porting the code,13 * If the bug only exists in Zig, something went wrong porting the code,
14 and you can run the C code and Zig code side by side in a debugger14 and you can run the C code and Zig code side by side in a debugger
15 to figure out what's happening differently.15 to figure out what's happening differently.
16
17To test Zig's compiler-rt, run this command from the build directory:
18
19```
20make install && ./zig test ../std/special/compiler_rt/index.zig --library c
21```
22
23The `--library c` argument omits compiler-rt from the generated test program,
24which prevents duplicate symbol linker errors for all the compiler-rt builtins.
std/special/compiler_rt/fixunstfsi_test.zig created+22
...@@ -0,0 +1,22 @@
1const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi;
2const assert = @import("../../debug.zig").assert;
3
4fn test__fixunstfsi(a: f128, expected: u32) {
5 const x = __fixunstfsi(a);
6 assert(x == expected);
7}
8
9const inf128 = @bitCast(f128, u128(0x7fff0000000000000000000000000000));
10
11test "fixunstfsi" {
12 test__fixunstfsi(inf128, 0xffffffff);
13 test__fixunstfsi(0, 0x0);
14 test__fixunstfsi(0x1.23456789abcdefp+5, 0x24);
15 test__fixunstfsi(0x1.23456789abcdefp-3, 0x0);
16 test__fixunstfsi(0x1.23456789abcdefp+20, 0x123456);
17 test__fixunstfsi(0x1.23456789abcdefp+40, 0xffffffff);
18 test__fixunstfsi(0x1.23456789abcdefp+256, 0xffffffff);
19 test__fixunstfsi(-0x1.23456789abcdefp+3, 0x0);
20
21 test__fixunstfsi(0x1.p+32, 0xFFFFFFFF);
22}
test/cases/cast.zig+17
...@@ -258,3 +258,20 @@ test "explicit cast float number literal to integer if no fraction component" {...@@ -258,3 +258,20 @@ test "explicit cast float number literal to integer if no fraction component" {
258 const y = i32(f32(1e4));258 const y = i32(f32(1e4));
259 assert(y == 10000);259 assert(y == 10000);
260}260}
261
262test "cast u128 to f128 and back" {
263 comptime testCast128();
264 testCast128();
265}
266
267fn testCast128() {
268 assert(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000);
269}
270
271fn cast128Int(x: f128) -> u128 {
272 @bitCast(u128, x)
273}
274
275fn cast128Float(x: u128) -> f128 {
276 @bitCast(f128, x)
277}