authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-14 02:48:16-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-14 02:48:16-04:00
log5989b88352c472cd146f7205cd46927bfded1108
treee0d8a7fb75bd6225e9705d34484a8d14ceeccf18
parent75b1c71cb300b88625cd93ebf21d41361b65e2c7

do not depend on __int128

closes #477

2 files changed, 17 insertions(+), 34 deletions(-)

src/bigint.cpp+17-24
...@@ -142,21 +142,6 @@ void bigint_init_unsigned(BigInt *dest, uint64_t x) {...@@ -142,21 +142,6 @@ void bigint_init_unsigned(BigInt *dest, uint64_t x) {
142 dest->is_negative = false;142 dest->is_negative = false;
143}143}
144144
145void bigint_init_u128(BigInt *dest, uint128_t x) {
146 uint64_t low = (uint64_t)(x & UINT64_MAX);
147 uint64_t high = (uint64_t)(x >> 64);
148
149 if (high == 0) {
150 return bigint_init_unsigned(dest, low);
151 }
152
153 dest->digit_count = 2;
154 dest->data.digits = allocate_nonzero<uint64_t>(2);
155 dest->data.digits[0] = low;
156 dest->data.digits[1] = high;
157 dest->is_negative = false;
158}
159
160void bigint_init_signed(BigInt *dest, int64_t x) {145void bigint_init_signed(BigInt *dest, int64_t x) {
161 if (x >= 0) {146 if (x >= 0) {
162 return bigint_init_unsigned(dest, x);147 return bigint_init_unsigned(dest, x);
...@@ -580,16 +565,24 @@ void bigint_sub_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t...@@ -580,16 +565,24 @@ void bigint_sub_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t
580 return bigint_add_wrap(dest, op1, &op2_negated, bit_count, is_signed);565 return bigint_add_wrap(dest, op1, &op2_negated, bit_count, is_signed);
581}566}
582567
583static void mul_overflow(uint64_t x, uint64_t y, uint64_t *result, uint64_t *carry) {568static void mul_overflow(uint64_t op1, uint64_t op2, uint64_t *lo, uint64_t *hi) {
584 if (!mul_u64_overflow(x, y, result)) {569 uint64_t u1 = (op1 & 0xffffffff);
585 *carry = 0;570 uint64_t v1 = (op2 & 0xffffffff);
586 return;571 uint64_t t = (u1 * v1);
587 }572 uint64_t w3 = (t & 0xffffffff);
573 uint64_t k = (t >> 32);
574
575 op1 >>= 32;
576 t = (op1 * v1) + k;
577 k = (t & 0xffffffff);
578 uint64_t w1 = (t >> 32);
579
580 op2 >>= 32;
581 t = (u1 * op2) + k;
582 k = (t >> 32);
588583
589 uint128_t big_x = x;584 *hi = (op1 * op2) + w1 + k;
590 uint128_t big_y = y;585 *lo = (t << 32) + w3;
591 uint128_t big_result = big_x * big_y;
592 *carry = big_result >> 64;
593}586}
594587
595static void mul_scalar(BigInt *dest, const BigInt *op, uint64_t scalar) {588static void mul_scalar(BigInt *dest, const BigInt *op, uint64_t scalar) {
src/bigint.hpp-10
...@@ -11,15 +11,6 @@...@@ -11,15 +11,6 @@
11#include <stdint.h>11#include <stdint.h>
12#include <stddef.h>12#include <stddef.h>
1313
14#if defined(_MSC_VER)
15 // TEMPORARY WORKAROUND FOR MSVC NOT SUPPORTING __int128
16 typedef long long int128_t;
17 typedef unsigned long long uint128_t;
18#else
19 typedef __int128 int128_t;
20 typedef unsigned __int128 uint128_t;
21#endif
22
23struct BigInt {14struct BigInt {
24 size_t digit_count;15 size_t digit_count;
25 union {16 union {
...@@ -39,7 +30,6 @@ enum Cmp {...@@ -39,7 +30,6 @@ enum Cmp {
39};30};
4031
41void bigint_init_unsigned(BigInt *dest, uint64_t x);32void bigint_init_unsigned(BigInt *dest, uint64_t x);
42void bigint_init_u128(BigInt *dest, uint128_t x);
43void bigint_init_signed(BigInt *dest, int64_t x);33void bigint_init_signed(BigInt *dest, int64_t x);
44void bigint_init_bigint(BigInt *dest, const BigInt *src);34void bigint_init_bigint(BigInt *dest, const BigInt *src);
45void bigint_init_bigfloat(BigInt *dest, const BigFloat *op);35void bigint_init_bigfloat(BigInt *dest, const BigFloat *op);