diff --git a/src/bigdecimal128.c b/src/bigdecimal128.c index 4e500c5..59b5bee 100644 --- a/src/bigdecimal128.c +++ b/src/bigdecimal128.c @@ -192,12 +192,9 @@ static buint_bool compare_(const BigDecimal128 *a, const BigDecimal128 *b, buint // at this point ltz(a)==ltz(b) is sure. // check #2: order of magnitude - BigUInt128 av = a->val; - BigUInt128 bv = b->val; - if (altz) { - bigint128_negate_assign(&av); - bigint128_negate_assign(&bv); - } + BigUInt128 av = bigint128_abs(&a->val, NULL); + BigUInt128 bv = bigint128_abs(&b->val, NULL); + UInt ooma_lo = oom_lb_(a->prec, &av); UInt ooma_hi = oom_ub_(a->prec, &av); UInt oomb_lo = oom_lb_(b->prec, &bv); @@ -237,16 +234,11 @@ static inline buint_bool addsub_safe_(BigDecimal128 *dest, const BigDecimal128 * fun[!add](&dest->val, &a->val, &b->val, &carry); dest->prec = a->prec; } else { - BigDecimal128 av = *a; - BigDecimal128 bv = *b; - buint_bool altz = bigint128_ltz(&a->val); - buint_bool bltz = bigint128_ltz(&b->val); - if (altz) { - bigint128_negate_assign(&av.val); - } - if (bltz) { - bigint128_negate_assign(&bv.val); - } + buint_bool altz; + buint_bool bltz; + BigDecimal128 av = {bigint128_abs(&a->val, &altz),a->prec}; + BigDecimal128 bv = {bigint128_abs(&b->val, &bltz),b->prec}; + retv = gen_common_hiprec_safe_(&av.prec, &bv.prec, &av.val, &bv.val); fun[!add != (altz != bltz)](&dest->val, &av.val, &bv.val, &carry); if (altz) { @@ -289,14 +281,14 @@ BigDecimal128 bigdecimal128_ctor_prec(const BigDecimal128 *a, UInt prec) { } buint_bool bigdecimal128_prec_safe(BigDecimal128 *dest, const BigDecimal128 *a, UInt prec) { - *dest = *a; - if (bigint128_ltz(&a->val)) { - bigint128_negate_assign(&dest->val); - buint_bool retv = tune_prec_(&dest->val, &dest->prec, prec, NULL); + buint_bool altz; + dest->val = bigint128_abs(&a->val, &altz); + dest->prec = a->prec; + buint_bool retv = tune_prec_(&dest->val, &dest->prec, prec, NULL); + if (altz) { bigint128_negate_assign(&dest->val); - return retv; } - return tune_prec_(&dest->val, &dest->prec, prec, NULL); + return retv; } BigDecimal128 bigdecimal128_add(const BigDecimal128 *a, const BigDecimal128 *b) { diff --git a/src/biguint128.c b/src/biguint128.c index 5409eff..6e73434 100644 --- a/src/biguint128.c +++ b/src/biguint128.c @@ -574,6 +574,25 @@ BigUInt128 bigint128_negate(const BigUInt128 *a) { return retv; } +BigUInt128 bigint128_abs(const BigUInt128 *a, buint_bool *result_inv) { + buint_bool inv = bigint128_ltz(a); + if (result_inv != NULL) { + *result_inv = inv; + } + return inv ? bigint128_negate(a) : *a; +} + +BigUInt128 *bigint128_abs_assign(BigUInt128 *a, buint_bool *result_inv) { + buint_bool inv = bigint128_ltz(a); + if (result_inv != NULL) { + *result_inv = inv; + } + if (inv) { + bigint128_negate_assign(a); + } + return a; +} + // END SUB // /////////////// @@ -855,17 +874,9 @@ BigUIntPair128 biguint128_div(const BigUInt128 *a, const BigUInt128 *b) { } BigUIntPair128 bigint128_div(const BigUInt128 *a, const BigUInt128 *b) { + buint_bool neg[2]; // work with copies - BigUInt128 ab[] = {biguint128_ctor_copy(a), biguint128_ctor_copy(b)}; - // check signs - buint_bool neg[] = {is_bigint_negative_(a), is_bigint_negative_(b)}; - // convert - for (unsigned int i = 0U; i<2; ++i) { - if (neg[i]) { - biguint128_dec(&ab[i]); - biguint128_not_assign(&ab[i]); - } - } + BigUInt128 ab[] = {bigint128_abs(a, &neg[0]), bigint128_abs(b, &neg[1])}; // calling the wrapped function BigUIntPair128 retv = biguint128_div(&ab[0], &ab[1]); diff --git a/src/biguint128.h b/src/biguint128.h index 3ff273f..3b11bce 100644 --- a/src/biguint128.h +++ b/src/biguint128.h @@ -161,6 +161,8 @@ void biguint128_sbc_replace(BigUInt128 *dest, const BigUInt128 *a, const BigUInt */ BigUInt128 bigint128_negate(const BigUInt128 *a); BigUInt128 *bigint128_negate_assign(BigUInt128 *a); +BigUInt128 bigint128_abs(const BigUInt128 *a, buint_bool *result_inv); +BigUInt128 *bigint128_abs_assign(BigUInt128 *a, buint_bool *result_inv); /** @brief Sub-assignment of UInt to biguint. diff --git a/tests/biguint128_eq_test.c b/tests/biguint128_eq_test.c index 8a760b0..e57b14a 100644 --- a/tests/biguint128_eq_test.c +++ b/tests/biguint128_eq_test.c @@ -18,6 +18,15 @@ CStr samplex[][SAMPLEX_W]= { {STR("1"), STR("1"), STR("0"), STR("0"), STR("1")} }; +#define SAMPLEY_W 3U +// a, b, lt, ilt, eq +CStr sampley[][SAMPLEY_W]= { + {STR("0"), STR("0"), STR("0")}, + {STR("1"), STR("1"), STR("0")}, + {STR("-1"), STR("1"), STR("1")}, + {STR("-0"), STR("0"), STR("0")} +}; + #define SAMPLEZ_W 3U // a, ltz, eqz CStr samplez[][SAMPLEZ_W]={ @@ -34,6 +43,48 @@ CStr samplez[][SAMPLEZ_W]={ }; const unsigned int samplez_len = ARRAYSIZE(samplez); +bool test_abs() { + bool pass = true; + for (unsigned int i=0; i