This commit is contained in:
parent
e81bcbab61
commit
3e6cfccb3b
205
lib/bigint.c
205
lib/bigint.c
@ -92,7 +92,6 @@ static const hcl_uint8_t debruijn_64[64] =
|
|||||||
# define LOG2_FOR_POW2(x) hcl_get_pos_of_msb_set_pow2(x)
|
# define LOG2_FOR_POW2(x) hcl_get_pos_of_msb_set_pow2(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (HCL_SIZEOF_OOW_T == HCL_SIZEOF_INT) && defined(HCL_HAVE_BUILTIN_UADD_OVERFLOW)
|
#if (HCL_SIZEOF_OOW_T == HCL_SIZEOF_INT) && defined(HCL_HAVE_BUILTIN_UADD_OVERFLOW)
|
||||||
# define oow_add_overflow(a,b,c) __builtin_uadd_overflow(a,b,c)
|
# define oow_add_overflow(a,b,c) __builtin_uadd_overflow(a,b,c)
|
||||||
#elif (HCL_SIZEOF_OOW_T == HCL_SIZEOF_LONG) && defined(HCL_HAVE_BUILTIN_UADDL_OVERFLOW)
|
#elif (HCL_SIZEOF_OOW_T == HCL_SIZEOF_LONG) && defined(HCL_HAVE_BUILTIN_UADDL_OVERFLOW)
|
||||||
@ -107,7 +106,6 @@ static HCL_INLINE int oow_add_overflow (hcl_oow_t a, hcl_oow_t b, hcl_oow_t* c)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (HCL_SIZEOF_OOW_T == HCL_SIZEOF_INT) && defined(HCL_HAVE_BUILTIN_UMUL_OVERFLOW)
|
#if (HCL_SIZEOF_OOW_T == HCL_SIZEOF_INT) && defined(HCL_HAVE_BUILTIN_UMUL_OVERFLOW)
|
||||||
# define oow_mul_overflow(a,b,c) __builtin_umul_overflow(a,b,c)
|
# define oow_mul_overflow(a,b,c) __builtin_umul_overflow(a,b,c)
|
||||||
#elif (HCL_SIZEOF_OOW_T == HCL_SIZEOF_LONG) && defined(HCL_HAVE_BUILTIN_UMULL_OVERFLOW)
|
#elif (HCL_SIZEOF_OOW_T == HCL_SIZEOF_LONG) && defined(HCL_HAVE_BUILTIN_UMULL_OVERFLOW)
|
||||||
@ -418,7 +416,7 @@ int hcl_inttoooi (hcl_t* hcl, hcl_oop_t x, hcl_ooi_t* i)
|
|||||||
|
|
||||||
/* do nothing. required macros are defined in hcl.h */
|
/* do nothing. required macros are defined in hcl.h */
|
||||||
|
|
||||||
#elif (HCL_SIZEOF_UINTMAX_T == HCL_SIZEOF_OOW_T * 2)
|
#elif (HCL_SIZEOF_UINTMAX_T == HCL_SIZEOF_OOW_T * 2) || (HCL_SIZEOF_UINTMAX_T == HCL_SIZEOF_OOW_T * 4)
|
||||||
static HCL_INLINE int bigint_to_uintmax (hcl_t* hcl, hcl_oop_t num, hcl_uintmax_t* w)
|
static HCL_INLINE int bigint_to_uintmax (hcl_t* hcl, hcl_oop_t num, hcl_uintmax_t* w)
|
||||||
{
|
{
|
||||||
HCL_ASSERT (hcl, HCL_OOP_IS_POINTER(num));
|
HCL_ASSERT (hcl, HCL_OOP_IS_POINTER(num));
|
||||||
@ -434,9 +432,25 @@ static HCL_INLINE int bigint_to_uintmax (hcl_t* hcl, hcl_oop_t num, hcl_uintmax_
|
|||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
*w = ((hcl_uintmax_t)HCL_OBJ_GET_WORD_VAL(num, 0) << HCL_LIW_BITS) | HCL_OBJ_GET_WORD_VAL(num, 1);
|
*w = ((hcl_uintmax_t)HCL_OBJ_GET_WORD_VAL(num, 0) << HCL_LIW_BITS) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_WORD_VAL(num, 1));
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
#if (HCL_SIZEOF_UINTMAX_T >= HCL_SIZEOF_OOW_T * 4)
|
||||||
|
case 3:
|
||||||
|
*w = ((hcl_uintmax_t)HCL_OBJ_GET_WORD_VAL(num, 0) << (HCL_LIW_BITS * 2)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_WORD_VAL(num, 1) << (HCL_LIW_BITS * 1)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_WORD_VAL(num, 2))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
*w = ((hcl_uintmax_t)HCL_OBJ_GET_WORD_VAL(num, 0) << (HCL_LIW_BITS * 3)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_WORD_VAL(num, 1) << (HCL_LIW_BITS * 2)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_WORD_VAL(num, 2) << (HCL_LIW_BITS * 1)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_WORD_VAL(num, 3))
|
||||||
|
goto done;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
goto oops_range;
|
goto oops_range;
|
||||||
}
|
}
|
||||||
@ -446,16 +460,39 @@ static HCL_INLINE int bigint_to_uintmax (hcl_t* hcl, hcl_oop_t num, hcl_uintmax_
|
|||||||
switch (HCL_OBJ_GET_SIZE(num))
|
switch (HCL_OBJ_GET_SIZE(num))
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
*w = ((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 0) << HCL_LIW_BITS) | HCL_OBJ_GET_HALFWORD_VAL(num, 1);
|
*w = ((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 0) << HCL_LIW_BITS) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 1));
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
*w = ((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 0) << HCL_LIW_BITS * 3) |
|
*w = ((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 0) << (HCL_LIW_BITS * 3)) |
|
||||||
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 1) << HCL_LIW_BITS * 2) |
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 1) << (HCL_LIW_BITS * 2)) |
|
||||||
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 2) << HCL_LIW_BITS * 1) |
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 2) << (HCL_LIW_BITS * 1)) |
|
||||||
HCL_OBJ_GET_HALFWORD_VAL(num, 3);
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 3));
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
#if (HCL_SIZEOF_UINTMAX_T >= HCL_SIZEOF_OOW_T * 4)
|
||||||
|
case 6:
|
||||||
|
*w = ((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 0) << (HCL_LIW_BITS * 5)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 1) << (HCL_LIW_BITS * 4)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 2) << (HCL_LIW_BITS * 3)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 3) << (HCL_LIW_BITS * 2)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 4) << (HCL_LIW_BITS * 1)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 5));
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
*w = ((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 0) << (HCL_LIW_BITS * 7)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 1) << (HCL_LIW_BITS * 6)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 2) << (HCL_LIW_BITS * 5)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 3) << (HCL_LIW_BITS * 4)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 4) << (HCL_LIW_BITS * 3)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 5) << (HCL_LIW_BITS * 2)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 6) << (HCL_LIW_BITS * 1)) |
|
||||||
|
((hcl_uintmax_t)HCL_OBJ_GET_HALFWORD_VAL(num, 7));
|
||||||
|
goto done;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
goto oops_range;
|
goto oops_range;
|
||||||
}
|
}
|
||||||
@ -529,7 +566,6 @@ int hcl_inttointmax (hcl_t* hcl, hcl_oop_t x, hcl_intmax_t* i)
|
|||||||
# error UNSUPPORTED UINTMAX SIZE
|
# error UNSUPPORTED UINTMAX SIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static HCL_INLINE hcl_oop_t make_bigint_with_oow (hcl_t* hcl, hcl_oow_t w)
|
static HCL_INLINE hcl_oop_t make_bigint_with_oow (hcl_t* hcl, hcl_oow_t w)
|
||||||
{
|
{
|
||||||
#if (HCL_LIW_BITS == HCL_OOW_BITS)
|
#if (HCL_LIW_BITS == HCL_OOW_BITS)
|
||||||
@ -605,7 +641,7 @@ static HCL_INLINE hcl_oop_t make_bloated_bigint_with_ooi (hcl_t* hcl, hcl_ooi_t
|
|||||||
z = make_nbigint(hcl, HCL_NULL, 1 + extra);
|
z = make_nbigint(hcl, HCL_NULL, 1 + extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
HCL_OBJ_SET_LIWORD_VAL (z, 0, w);
|
HCL_OBJ_SET_LIWORD_VAL (z, 0, w);
|
||||||
return z;
|
return z;
|
||||||
|
|
||||||
@ -630,7 +666,7 @@ static HCL_INLINE hcl_oop_t make_bloated_bigint_with_ooi (hcl_t* hcl, hcl_ooi_t
|
|||||||
z = make_nbigint(hcl, HCL_NULL, (hw[1] > 0? 2: 1) + extra);
|
z = make_nbigint(hcl, HCL_NULL, (hw[1] > 0? 2: 1) + extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
HCL_OBJ_SET_LIWORD_VAL (z, 0, hw[0]);
|
HCL_OBJ_SET_LIWORD_VAL (z, 0, hw[0]);
|
||||||
if (hw[1] > 0) HCL_OBJ_SET_LIWORD_VAL (z, 1, hw[1]);
|
if (hw[1] > 0) HCL_OBJ_SET_LIWORD_VAL (z, 1, hw[1]);
|
||||||
return z;
|
return z;
|
||||||
@ -760,7 +796,7 @@ static HCL_INLINE hcl_oop_t expand_bigint (hcl_t* hcl, hcl_oop_t oop, hcl_oow_t
|
|||||||
hcl_pushvolat (hcl, &oop);
|
hcl_pushvolat (hcl, &oop);
|
||||||
z = hcl_instantiate(hcl, (hcl_oop_class_t)HCL_OBJ_GET_CLASS(oop), HCL_NULL, count + inc);
|
z = hcl_instantiate(hcl, (hcl_oop_class_t)HCL_OBJ_GET_CLASS(oop), HCL_NULL, count + inc);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!z)
|
if (HCL_UNLIKELY(!z))
|
||||||
{
|
{
|
||||||
const hcl_ooch_t* orgmsg = hcl_backuperrmsg(hcl);
|
const hcl_ooch_t* orgmsg = hcl_backuperrmsg(hcl);
|
||||||
hcl_seterrbfmt (hcl, HCL_ERRNUM(hcl), "unable to clone bigint %O for expansion - %s", oop, orgmsg);
|
hcl_seterrbfmt (hcl, HCL_ERRNUM(hcl), "unable to clone bigint %O for expansion - %s", oop, orgmsg);
|
||||||
@ -782,12 +818,10 @@ static HCL_INLINE hcl_oop_t _clone_bigint(hcl_t* hcl, hcl_oop_t oop, hcl_oow_t c
|
|||||||
HCL_ASSERT (hcl, HCL_OOP_IS_POINTER(oop));
|
HCL_ASSERT (hcl, HCL_OOP_IS_POINTER(oop));
|
||||||
if (count <= 0) count = HCL_OBJ_GET_SIZE(oop);
|
if (count <= 0) count = HCL_OBJ_GET_SIZE(oop);
|
||||||
|
|
||||||
hcl_pushvolat (hcl, (hcl_oop_t*)&_class);
|
|
||||||
hcl_pushvolat (hcl, &oop);
|
hcl_pushvolat (hcl, &oop);
|
||||||
z = hcl_instantiate(hcl, _class, HCL_NULL, count);
|
z = hcl_instantiate(hcl, _class, HCL_NULL, count);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
hcl_popvolat (hcl);
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
if (!z) return HCL_NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
@ -986,7 +1020,7 @@ static HCL_INLINE int is_equal_unsigned (hcl_oop_t x, hcl_oop_t y)
|
|||||||
static HCL_INLINE int is_equal (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
static HCL_INLINE int is_equal (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
||||||
{
|
{
|
||||||
/* check if two large integers are equal to each other */
|
/* check if two large integers are equal to each other */
|
||||||
/*return HCL_OBJ_GET_FLAGS_BRAND(x) == HCL_OBJ_GET_FLAGS_BRAND(y) && HCL_OBJ_GET_SIZE(x) == HCL_OBJ_GET_SIZE(y) &&
|
/*return HCL_OBJ_GET_CLASS(x) == HCL_OBJ_GET_CLASS(y) && HCL_OBJ_GET_SIZE(x) == HCL_OBJ_GET_SIZE(y) &&
|
||||||
HCL_MEMCMP(((hcl_oop_liword_t)x)->slot, ((hcl_oop_liword_t)y)->slot, HCL_OBJ_GET_SIZE(x) * HCL_SIZEOF(hcl_liw_t)) == 0;*/
|
HCL_MEMCMP(((hcl_oop_liword_t)x)->slot, ((hcl_oop_liword_t)y)->slot, HCL_OBJ_GET_SIZE(x) * HCL_SIZEOF(hcl_liw_t)) == 0;*/
|
||||||
return HCL_OBJ_GET_CLASS(x) == HCL_OBJ_GET_CLASS(y) && HCL_OBJ_GET_SIZE(x) == HCL_OBJ_GET_SIZE(y) && is_equal_unsigned(x, y);
|
return HCL_OBJ_GET_CLASS(x) == HCL_OBJ_GET_CLASS(y) && HCL_OBJ_GET_SIZE(x) == HCL_OBJ_GET_SIZE(y) && is_equal_unsigned(x, y);
|
||||||
}
|
}
|
||||||
@ -1423,13 +1457,13 @@ static HCL_INLINE hcl_oow_t multiply_unsigned_array_karatsuba (hcl_t* hcl, const
|
|||||||
tmplen[0] = ndigits_xh + ndigits_yh;
|
tmplen[0] = ndigits_xh + ndigits_yh;
|
||||||
tmplen[1] = ndigits_yl + ndigits_yh + 1;
|
tmplen[1] = ndigits_yl + ndigits_yh + 1;
|
||||||
if (tmplen[1] < tmplen[0]) tmplen[1] = tmplen[0];
|
if (tmplen[1] < tmplen[0]) tmplen[1] = tmplen[0];
|
||||||
tmp[1] = (hcl_liw_t*)hcl_callocmem(hcl, HCL_SIZEOF(hcl_liw_t) * tmplen[1]); /* TODO: should i use the object memory? */
|
tmp[1] = (hcl_liw_t*)hcl_callocmem(hcl, HCL_SIZEOF(hcl_liw_t) * tmplen[1]); /* TODO: should i use the object memory? if not, reuse the buffer and minimize memory allocation */
|
||||||
if (!tmp[1]) goto oops;
|
if (HCL_UNLIKELY(!tmp[1])) goto oops;
|
||||||
|
|
||||||
/* make a temporary for (a0 + a1) and (a0 * b0) */
|
/* make a temporary for (a0 + a1) and (a0 * b0) */
|
||||||
tmplen[0] = ndigits_xl + ndigits_yl + 1;
|
tmplen[0] = ndigits_xl + ndigits_yl + 1;
|
||||||
tmp[0] = (hcl_liw_t*)hcl_callocmem(hcl, HCL_SIZEOF(hcl_liw_t) * tmplen[0]);
|
tmp[0] = (hcl_liw_t*)hcl_callocmem(hcl, HCL_SIZEOF(hcl_liw_t) * tmplen[0]);
|
||||||
if (!tmp[0]) goto oops;
|
if (HCL_UNLIKELY(!tmp[0])) goto oops;
|
||||||
|
|
||||||
/* tmp[0] = a0 + a1 */
|
/* tmp[0] = a0 + a1 */
|
||||||
tmplen[0] = add_unsigned_array(x, ndigits_xl, x + nshifts, ndigits_xh, tmp[0]);
|
tmplen[0] = add_unsigned_array(x, ndigits_xl, x + nshifts, ndigits_xh, tmp[0]);
|
||||||
@ -1560,12 +1594,12 @@ oops:
|
|||||||
tmplen[0] = ndigits_yl + ndigits_yh + 1;
|
tmplen[0] = ndigits_yl + ndigits_yh + 1;
|
||||||
tmplen[1] = ndigits_xh + ndigits_yh;
|
tmplen[1] = ndigits_xh + ndigits_yh;
|
||||||
if (tmplen[1] < tmplen[0]) tmplen[1] = tmplen[0];
|
if (tmplen[1] < tmplen[0]) tmplen[1] = tmplen[0];
|
||||||
tmp[1] = hcl_callocmem(hcl, HCL_SIZEOF(hcl_liw_t) * tmplen[1]);
|
tmp[1] = (hcl_liw_t*)hcl_callocmem(hcl, HCL_SIZEOF(hcl_liw_t) * tmplen[1]);
|
||||||
if (!tmp[1]) goto oops;
|
if (!tmp[1]) goto oops;
|
||||||
|
|
||||||
/* make a temporary for (a0 + a1) and (a0 * b0) */
|
/* make a temporary for (a0 + a1) and (a0 * b0) */
|
||||||
tmplen[0] = ndigits_xl + ndigits_yl;
|
tmplen[0] = ndigits_xl + ndigits_yl;
|
||||||
tmp[0] = hcl_callocmem(hcl, HCL_SIZEOF(hcl_liw_t) * tmplen[0]);
|
tmp[0] = (hcl_liw_t*)hcl_callocmem(hcl, HCL_SIZEOF(hcl_liw_t) * tmplen[0]);
|
||||||
if (!tmp[0]) goto oops;
|
if (!tmp[0]) goto oops;
|
||||||
|
|
||||||
/* tmp[0] = a0 + a1 */
|
/* tmp[0] = a0 + a1 */
|
||||||
@ -1576,7 +1610,7 @@ oops:
|
|||||||
|
|
||||||
/* tmp[2] = (a0 + a1) * (b0 + b1) */
|
/* tmp[2] = (a0 + a1) * (b0 + b1) */
|
||||||
tmplen[2] = tmplen[0] + tmplen[1];
|
tmplen[2] = tmplen[0] + tmplen[1];
|
||||||
tmp[2] = hcl_callocmem (hcl, HCL_SIZEOF(hcl_liw_t) * tmplen[2]);
|
tmp[2] = (hcl_liw_t*)hcl_callocmem(hcl, HCL_SIZEOF(hcl_liw_t) * tmplen[2]);
|
||||||
if (!tmp[2]) goto oops;
|
if (!tmp[2]) goto oops;
|
||||||
if (CANNOT_KARATSUBA(hcl, tmplen[0], tmplen[1]))
|
if (CANNOT_KARATSUBA(hcl, tmplen[0], tmplen[1]))
|
||||||
{
|
{
|
||||||
@ -2113,7 +2147,7 @@ static hcl_oop_t add_unsigned_integers (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
z = hcl_instantiate(hcl, (hcl_oop_class_t)HCL_OBJ_GET_CLASS(x), HCL_NULL, zs);
|
z = hcl_instantiate(hcl, (hcl_oop_class_t)HCL_OBJ_GET_CLASS(x), HCL_NULL, zs);
|
||||||
hcl_popvolats (hcl, 2);
|
hcl_popvolats (hcl, 2);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
add_unsigned_array (
|
add_unsigned_array (
|
||||||
((hcl_oop_liword_t)x)->slot, as,
|
((hcl_oop_liword_t)x)->slot, as,
|
||||||
@ -2134,7 +2168,7 @@ static hcl_oop_t subtract_unsigned_integers (hcl_t* hcl, hcl_oop_t x, hcl_oop_t
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
z = make_pbigint(hcl, HCL_NULL, HCL_OBJ_GET_SIZE(x));
|
z = make_pbigint(hcl, HCL_NULL, HCL_OBJ_GET_SIZE(x));
|
||||||
hcl_popvolats (hcl, 2);
|
hcl_popvolats (hcl, 2);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
subtract_unsigned_array (hcl,
|
subtract_unsigned_array (hcl,
|
||||||
((hcl_oop_liword_t)x)->slot, HCL_OBJ_GET_SIZE(x),
|
((hcl_oop_liword_t)x)->slot, HCL_OBJ_GET_SIZE(x),
|
||||||
@ -2161,7 +2195,7 @@ static hcl_oop_t multiply_unsigned_integers (hcl_t* hcl, hcl_oop_t x, hcl_oop_t
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
z = make_pbigint(hcl, HCL_NULL, xs + ys);
|
z = make_pbigint(hcl, HCL_NULL, xs + ys);
|
||||||
hcl_popvolats (hcl, 2);
|
hcl_popvolats (hcl, 2);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
#if defined(HCL_ENABLE_KARATSUBA)
|
#if defined(HCL_ENABLE_KARATSUBA)
|
||||||
if (CANNOT_KARATSUBA(hcl, xs, ys))
|
if (CANNOT_KARATSUBA(hcl, xs, ys))
|
||||||
@ -2229,7 +2263,7 @@ static hcl_oop_t divide_unsigned_integers (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y,
|
|||||||
#else
|
#else
|
||||||
qq = make_pbigint(hcl, HCL_NULL, HCL_OBJ_GET_SIZE(x));
|
qq = make_pbigint(hcl, HCL_NULL, HCL_OBJ_GET_SIZE(x));
|
||||||
#endif
|
#endif
|
||||||
if (!qq)
|
if (HCL_UNLIKELY(!qq))
|
||||||
{
|
{
|
||||||
hcl_popvolats (hcl, 2);
|
hcl_popvolats (hcl, 2);
|
||||||
return HCL_NULL;
|
return HCL_NULL;
|
||||||
@ -2244,8 +2278,7 @@ static hcl_oop_t divide_unsigned_integers (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y,
|
|||||||
rr = make_pbigint(hcl, HCL_NULL, HCL_OBJ_GET_SIZE(y) + 1);
|
rr = make_pbigint(hcl, HCL_NULL, HCL_OBJ_GET_SIZE(y) + 1);
|
||||||
#endif
|
#endif
|
||||||
hcl_popvolats (hcl, 3);
|
hcl_popvolats (hcl, 3);
|
||||||
if (!rr) return HCL_NULL;
|
if (HCL_UNLIKELY(!rr)) return HCL_NULL;
|
||||||
|
|
||||||
|
|
||||||
#if defined(USE_DIVIDE_UNSIGNED_ARRAY3)
|
#if defined(USE_DIVIDE_UNSIGNED_ARRAY3)
|
||||||
divide_unsigned_array3 (hcl,
|
divide_unsigned_array3 (hcl,
|
||||||
@ -2256,7 +2289,8 @@ static hcl_oop_t divide_unsigned_integers (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y,
|
|||||||
#endif
|
#endif
|
||||||
((hcl_oop_liword_t)x)->slot, HCL_OBJ_GET_SIZE(x),
|
((hcl_oop_liword_t)x)->slot, HCL_OBJ_GET_SIZE(x),
|
||||||
((hcl_oop_liword_t)y)->slot, HCL_OBJ_GET_SIZE(y),
|
((hcl_oop_liword_t)y)->slot, HCL_OBJ_GET_SIZE(y),
|
||||||
((hcl_oop_liword_t)qq)->slot, ((hcl_oop_liword_t)rr)->slot);
|
((hcl_oop_liword_t)qq)->slot, ((hcl_oop_liword_t)rr)->slot
|
||||||
|
);
|
||||||
|
|
||||||
*r = rr;
|
*r = rr;
|
||||||
return qq;
|
return qq;
|
||||||
@ -2296,7 +2330,7 @@ hcl_oop_t hcl_addints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
x = make_bigint_with_ooi(hcl, v);
|
x = make_bigint_with_ooi(hcl, v);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!x) return HCL_NULL;
|
if (HCL_UNLIKELY(!x)) return HCL_NULL;
|
||||||
}
|
}
|
||||||
else if (HCL_OOP_IS_SMOOI(y))
|
else if (HCL_OOP_IS_SMOOI(y))
|
||||||
{
|
{
|
||||||
@ -2308,7 +2342,7 @@ hcl_oop_t hcl_addints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &x);
|
hcl_pushvolat (hcl, &x);
|
||||||
y = make_bigint_with_ooi(hcl, v);
|
y = make_bigint_with_ooi(hcl, v);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!y) return HCL_NULL;
|
if (HCL_UNLIKELY(!y)) return HCL_NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2404,7 +2438,7 @@ hcl_oop_t hcl_subints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
x = make_bigint_with_ooi(hcl, v);
|
x = make_bigint_with_ooi(hcl, v);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!x) return HCL_NULL;
|
if (HCL_UNLIKELY(!x)) return HCL_NULL;
|
||||||
}
|
}
|
||||||
else if (HCL_OOP_IS_SMOOI(y))
|
else if (HCL_OOP_IS_SMOOI(y))
|
||||||
{
|
{
|
||||||
@ -2416,7 +2450,7 @@ hcl_oop_t hcl_subints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &x);
|
hcl_pushvolat (hcl, &x);
|
||||||
y = make_bigint_with_ooi(hcl, v);
|
y = make_bigint_with_ooi(hcl, v);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!y) return HCL_NULL;
|
if (HCL_UNLIKELY(!y)) return HCL_NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2428,7 +2462,7 @@ hcl_oop_t hcl_subints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
{
|
{
|
||||||
neg = HCL_IS_NBIGINT(hcl, x);
|
neg = HCL_IS_NBIGINT(hcl, x);
|
||||||
z = add_unsigned_integers(hcl, x, y);
|
z = add_unsigned_integers(hcl, x, y);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
if (neg) HCL_OBJ_SET_CLASS (z, (hcl_oop_t)hcl->c_large_negative_integer);
|
if (neg) HCL_OBJ_SET_CLASS (z, (hcl_oop_t)hcl->c_large_negative_integer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2695,7 +2729,7 @@ hcl_oop_t hcl_divints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y, int modulo, hcl_oop
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
x = make_bigint_with_ooi(hcl, xv);
|
x = make_bigint_with_ooi(hcl, xv);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!x) return HCL_NULL;
|
if (HCL_UNLIKELY(!x)) return HCL_NULL;
|
||||||
}
|
}
|
||||||
else if (HCL_OOP_IS_SMOOI(y))
|
else if (HCL_OOP_IS_SMOOI(y))
|
||||||
{
|
{
|
||||||
@ -2714,13 +2748,13 @@ hcl_oop_t hcl_divints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y, int modulo, hcl_oop
|
|||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
z = clone_bigint(hcl, x, HCL_OBJ_GET_SIZE(x));
|
z = clone_bigint(hcl, x, HCL_OBJ_GET_SIZE(x));
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
if (rem) *rem = HCL_SMOOI_TO_OOP(0);
|
if (rem) *rem = HCL_SMOOI_TO_OOP(0);
|
||||||
return z;
|
return z;
|
||||||
|
|
||||||
case -1:
|
case -1:
|
||||||
z = clone_bigint_negated(hcl, x, HCL_OBJ_GET_SIZE(x));
|
z = clone_bigint_negated(hcl, x, HCL_OBJ_GET_SIZE(x));
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
if (rem) *rem = HCL_SMOOI_TO_OOP(0);
|
if (rem) *rem = HCL_SMOOI_TO_OOP(0);
|
||||||
return z;
|
return z;
|
||||||
|
|
||||||
@ -2741,7 +2775,7 @@ hcl_oop_t hcl_divints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y, int modulo, hcl_oop
|
|||||||
y_neg_sign = (yv < 0);
|
y_neg_sign = (yv < 0);
|
||||||
|
|
||||||
z = clone_bigint_to_positive(hcl, x, HCL_OBJ_GET_SIZE(x));
|
z = clone_bigint_to_positive(hcl, x, HCL_OBJ_GET_SIZE(x));
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
zw = ((hcl_oop_liword_t)z)->slot;
|
zw = ((hcl_oop_liword_t)z)->slot;
|
||||||
zs = HCL_OBJ_GET_SIZE(z);
|
zs = HCL_OBJ_GET_SIZE(z);
|
||||||
@ -2777,7 +2811,6 @@ hcl_oop_t hcl_divints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y, int modulo, hcl_oop
|
|||||||
if (HCL_UNLIKELY(!r)) return HCL_NULL;
|
if (HCL_UNLIKELY(!r)) return HCL_NULL;
|
||||||
*rem = r;
|
*rem = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2791,7 +2824,7 @@ hcl_oop_t hcl_divints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y, int modulo, hcl_oop
|
|||||||
hcl_pushvolat (hcl, &x);
|
hcl_pushvolat (hcl, &x);
|
||||||
y = make_bigint_with_ooi(hcl, yv);
|
y = make_bigint_with_ooi(hcl, yv);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!y) return HCL_NULL;
|
if (HCL_UNLIKELY(!y)) return HCL_NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2807,7 +2840,7 @@ hcl_oop_t hcl_divints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y, int modulo, hcl_oop
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
z = divide_unsigned_integers(hcl, x, y, &r);
|
z = divide_unsigned_integers(hcl, x, y, &r);
|
||||||
hcl_popvolats (hcl, 2);
|
hcl_popvolats (hcl, 2);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
if (x_neg_sign)
|
if (x_neg_sign)
|
||||||
{
|
{
|
||||||
@ -2824,7 +2857,7 @@ hcl_oop_t hcl_divints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y, int modulo, hcl_oop
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
r = normalize_bigint(hcl, r);
|
r = normalize_bigint(hcl, r);
|
||||||
hcl_popvolats (hcl, 2);
|
hcl_popvolats (hcl, 2);
|
||||||
if (!r) return HCL_NULL;
|
if (HCL_UNLIKELY(!r)) return HCL_NULL;
|
||||||
|
|
||||||
if (r != HCL_SMOOI_TO_OOP(0) && modulo)
|
if (r != HCL_SMOOI_TO_OOP(0) && modulo)
|
||||||
{
|
{
|
||||||
@ -2834,17 +2867,17 @@ hcl_oop_t hcl_divints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y, int modulo, hcl_oop
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
r = hcl_addints(hcl, r, y);
|
r = hcl_addints(hcl, r, y);
|
||||||
hcl_popvolats (hcl, 2);
|
hcl_popvolats (hcl, 2);
|
||||||
if (!r) return HCL_NULL;
|
if (HCL_UNLIKELY(!r)) return HCL_NULL;
|
||||||
|
|
||||||
hcl_pushvolat (hcl, &r);
|
hcl_pushvolat (hcl, &r);
|
||||||
z = normalize_bigint(hcl, z);
|
z = normalize_bigint(hcl, z);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
hcl_pushvolat (hcl, &r);
|
hcl_pushvolat (hcl, &r);
|
||||||
z = hcl_subints(hcl, z, HCL_SMOOI_TO_OOP(1));
|
z = hcl_subints(hcl, z, HCL_SMOOI_TO_OOP(1));
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
*rem = r;
|
*rem = r;
|
||||||
return z;
|
return z;
|
||||||
@ -2854,7 +2887,7 @@ hcl_oop_t hcl_divints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y, int modulo, hcl_oop
|
|||||||
/* remainder is not needed at all */
|
/* remainder is not needed at all */
|
||||||
/* TODO: subtract 1 without normalization??? */
|
/* TODO: subtract 1 without normalization??? */
|
||||||
z = normalize_bigint(hcl, z);
|
z = normalize_bigint(hcl, z);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
return hcl_subints(hcl, z, HCL_SMOOI_TO_OOP(1));
|
return hcl_subints(hcl, z, HCL_SMOOI_TO_OOP(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2864,7 +2897,7 @@ hcl_oop_t hcl_divints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y, int modulo, hcl_oop
|
|||||||
hcl_pushvolat (hcl, &z);
|
hcl_pushvolat (hcl, &z);
|
||||||
r = normalize_bigint(hcl, r);
|
r = normalize_bigint(hcl, r);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!r) return HCL_NULL;
|
if (HCL_UNLIKELY(!r)) return HCL_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hcl_pushvolat (hcl, &r);
|
hcl_pushvolat (hcl, &r);
|
||||||
@ -3089,7 +3122,7 @@ hcl_oop_t hcl_bitandints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
x = make_bigint_with_ooi(hcl, v);
|
x = make_bigint_with_ooi(hcl, v);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!x) return HCL_NULL;
|
if (HCL_UNLIKELY(!x)) return HCL_NULL;
|
||||||
|
|
||||||
goto bigint_and_bigint;
|
goto bigint_and_bigint;
|
||||||
}
|
}
|
||||||
@ -3105,7 +3138,7 @@ hcl_oop_t hcl_bitandints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &x);
|
hcl_pushvolat (hcl, &x);
|
||||||
y = make_bigint_with_ooi (hcl, v);
|
y = make_bigint_with_ooi (hcl, v);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!x) return HCL_NULL;
|
if (HCL_UNLIKELY(!x)) return HCL_NULL;
|
||||||
|
|
||||||
goto bigint_and_bigint;
|
goto bigint_and_bigint;
|
||||||
}
|
}
|
||||||
@ -3160,7 +3193,7 @@ hcl_oop_t hcl_bitandints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
z = make_pbigint(hcl, HCL_NULL, zalloc);
|
z = make_pbigint(hcl, HCL_NULL, zalloc);
|
||||||
hcl_popvolats (hcl, 2);
|
hcl_popvolats (hcl, 2);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
if (negx && negy)
|
if (negx && negy)
|
||||||
{
|
{
|
||||||
@ -3302,7 +3335,7 @@ hcl_oop_t hcl_bitorints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
x = make_bigint_with_ooi(hcl, v);
|
x = make_bigint_with_ooi(hcl, v);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!x) return HCL_NULL;
|
if (HCL_UNLIKELY(!x)) return HCL_NULL;
|
||||||
|
|
||||||
goto bigint_and_bigint;
|
goto bigint_and_bigint;
|
||||||
}
|
}
|
||||||
@ -3318,7 +3351,7 @@ hcl_oop_t hcl_bitorints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &x);
|
hcl_pushvolat (hcl, &x);
|
||||||
y = make_bigint_with_ooi(hcl, v);
|
y = make_bigint_with_ooi(hcl, v);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!x) return HCL_NULL;
|
if (HCL_UNLIKELY(!x)) return HCL_NULL;
|
||||||
|
|
||||||
goto bigint_and_bigint;
|
goto bigint_and_bigint;
|
||||||
}
|
}
|
||||||
@ -3380,7 +3413,7 @@ hcl_oop_t hcl_bitorints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
z = make_pbigint(hcl, HCL_NULL, zalloc);
|
z = make_pbigint(hcl, HCL_NULL, zalloc);
|
||||||
hcl_popvolats (hcl, 2);
|
hcl_popvolats (hcl, 2);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
if (negx && negy)
|
if (negx && negy)
|
||||||
{
|
{
|
||||||
@ -3520,7 +3553,7 @@ hcl_oop_t hcl_bitxorints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
x = make_bigint_with_ooi (hcl, v);
|
x = make_bigint_with_ooi (hcl, v);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!x) return HCL_NULL;
|
if (HCL_UNLIKELY(!x)) return HCL_NULL;
|
||||||
|
|
||||||
goto bigint_and_bigint;
|
goto bigint_and_bigint;
|
||||||
}
|
}
|
||||||
@ -3536,7 +3569,7 @@ hcl_oop_t hcl_bitxorints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &x);
|
hcl_pushvolat (hcl, &x);
|
||||||
y = make_bigint_with_ooi (hcl, v);
|
y = make_bigint_with_ooi (hcl, v);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!x) return HCL_NULL;
|
if (HCL_UNLIKELY(!x)) return HCL_NULL;
|
||||||
|
|
||||||
goto bigint_and_bigint;
|
goto bigint_and_bigint;
|
||||||
}
|
}
|
||||||
@ -3756,7 +3789,7 @@ hcl_oop_t hcl_bitinvint (hcl_t* hcl, hcl_oop_t x)
|
|||||||
hcl_pushvolat (hcl, &x);
|
hcl_pushvolat (hcl, &x);
|
||||||
z = make_pbigint(hcl, HCL_NULL, zalloc);
|
z = make_pbigint(hcl, HCL_NULL, zalloc);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
if (negx)
|
if (negx)
|
||||||
{
|
{
|
||||||
@ -3828,7 +3861,7 @@ static HCL_INLINE hcl_oop_t rshift_negative_bigint (hcl_t* hcl, hcl_oop_t x, hcl
|
|||||||
/* +1 for the second inversion below */
|
/* +1 for the second inversion below */
|
||||||
z = make_nbigint(hcl, HCL_NULL, xs + 1);
|
z = make_nbigint(hcl, HCL_NULL, xs + 1);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
/* the following lines roughly for 'z = hcl_bitinv (hcl, x)' */
|
/* the following lines roughly for 'z = hcl_bitinv (hcl, x)' */
|
||||||
carry = 1;
|
carry = 1;
|
||||||
@ -3851,7 +3884,6 @@ static HCL_INLINE hcl_oop_t rshift_negative_bigint (hcl_t* hcl, hcl_oop_t x, hcl
|
|||||||
}
|
}
|
||||||
HCL_OBJ_SET_LIWORD_VAL (z, xs, ~(hcl_liw_t)0);
|
HCL_OBJ_SET_LIWORD_VAL (z, xs, ~(hcl_liw_t)0);
|
||||||
|
|
||||||
|
|
||||||
carry = 1;
|
carry = 1;
|
||||||
for (i = 0; i <= xs; i++)
|
for (i = 0; i <= xs; i++)
|
||||||
{
|
{
|
||||||
@ -3898,7 +3930,7 @@ static HCL_INLINE hcl_oop_t rshift_negative_bigint_and_normalize (hcl_t* hcl, hc
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
z = rshift_negative_bigint(hcl, x, shift);
|
z = rshift_negative_bigint(hcl, x, shift);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
/* y is a negative number. use hcl_addints() until it becomes 0 */
|
/* y is a negative number. use hcl_addints() until it becomes 0 */
|
||||||
hcl_pushvolat (hcl, &z);
|
hcl_pushvolat (hcl, &z);
|
||||||
@ -3921,7 +3953,7 @@ static HCL_INLINE hcl_oop_t rshift_negative_bigint_and_normalize (hcl_t* hcl, hc
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
x = normalize_bigint(hcl, z);
|
x = normalize_bigint(hcl, z);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!x) return HCL_NULL;
|
if (HCL_UNLIKELY(!x)) return HCL_NULL;
|
||||||
|
|
||||||
if (HCL_OOP_IS_SMOOI(x))
|
if (HCL_OOP_IS_SMOOI(x))
|
||||||
{
|
{
|
||||||
@ -3971,7 +4003,7 @@ static HCL_INLINE hcl_oop_t rshift_positive_bigint_and_normalize (hcl_t* hcl, hc
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
z = clone_bigint(hcl, x, zs);
|
z = clone_bigint(hcl, x, zs);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
/* for convenience in subtraction below.
|
/* for convenience in subtraction below.
|
||||||
* it could be HCL_TYPE_MAX(hcl_oow_t)
|
* it could be HCL_TYPE_MAX(hcl_oow_t)
|
||||||
@ -4033,14 +4065,14 @@ static HCL_INLINE hcl_oop_t lshift_bigint_and_normalize (hcl_t* hcl, hcl_oop_t x
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
z = expand_bigint(hcl, x, wshift);
|
z = expand_bigint(hcl, x, wshift);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
lshift_unsigned_array (((hcl_oop_liword_t)z)->slot, HCL_OBJ_GET_SIZE(z), shift);
|
lshift_unsigned_array (((hcl_oop_liword_t)z)->slot, HCL_OBJ_GET_SIZE(z), shift);
|
||||||
|
|
||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
x = normalize_bigint(hcl, z);
|
x = normalize_bigint(hcl, z);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!x) return HCL_NULL;
|
if (HCL_UNLIKELY(!x)) return HCL_NULL;
|
||||||
|
|
||||||
hcl_pushvolat (hcl, &x);
|
hcl_pushvolat (hcl, &x);
|
||||||
y = hcl_subints(hcl, y, HCL_SMOOI_TO_OOP(shift));
|
y = hcl_subints(hcl, y, HCL_SMOOI_TO_OOP(shift));
|
||||||
@ -4096,7 +4128,7 @@ hcl_oop_t hcl_bitshiftint (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
if (v2 > wshift * HCL_LIW_BITS) wshift++;
|
if (v2 > wshift * HCL_LIW_BITS) wshift++;
|
||||||
|
|
||||||
z = make_bloated_bigint_with_ooi(hcl, v1, wshift);
|
z = make_bloated_bigint_with_ooi(hcl, v1, wshift);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
lshift_unsigned_array (((hcl_oop_liword_t)z)->slot, HCL_OBJ_GET_SIZE(z), v2);
|
lshift_unsigned_array (((hcl_oop_liword_t)z)->slot, HCL_OBJ_GET_SIZE(z), v2);
|
||||||
return normalize_bigint(hcl, z);
|
return normalize_bigint(hcl, z);
|
||||||
@ -4169,7 +4201,7 @@ hcl_oop_t hcl_bitshiftint (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
hcl_pushvolat (hcl, &y);
|
hcl_pushvolat (hcl, &y);
|
||||||
x = make_bigint_with_ooi(hcl, v);
|
x = make_bigint_with_ooi(hcl, v);
|
||||||
hcl_popvolat (hcl);
|
hcl_popvolat (hcl);
|
||||||
if (!x) return HCL_NULL;
|
if (HCL_UNLIKELY(!x)) return HCL_NULL;
|
||||||
|
|
||||||
goto bigint_and_bigint;
|
goto bigint_and_bigint;
|
||||||
}
|
}
|
||||||
@ -4254,7 +4286,7 @@ hcl_oop_t hcl_bitshiftint (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
if (shift > wshift * HCL_LIW_BITS) wshift++;
|
if (shift > wshift * HCL_LIW_BITS) wshift++;
|
||||||
|
|
||||||
z = expand_bigint(hcl, x, wshift);
|
z = expand_bigint(hcl, x, wshift);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
|
|
||||||
lshift_unsigned_array (((hcl_oop_liword_t)z)->slot, HCL_OBJ_GET_SIZE(z), shift);
|
lshift_unsigned_array (((hcl_oop_liword_t)z)->slot, HCL_OBJ_GET_SIZE(z), shift);
|
||||||
}
|
}
|
||||||
@ -4268,12 +4300,12 @@ hcl_oop_t hcl_bitshiftint (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
if (negx)
|
if (negx)
|
||||||
{
|
{
|
||||||
z = rshift_negative_bigint(hcl, x, shift);
|
z = rshift_negative_bigint(hcl, x, shift);
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
z = clone_bigint(hcl, x, HCL_OBJ_GET_SIZE(x));
|
z = clone_bigint(hcl, x, HCL_OBJ_GET_SIZE(x));
|
||||||
if (!z) return HCL_NULL;
|
if (HCL_UNLIKELY(!z)) return HCL_NULL;
|
||||||
rshift_unsigned_array (((hcl_oop_liword_t)z)->slot, HCL_OBJ_GET_SIZE(z), shift);
|
rshift_unsigned_array (((hcl_oop_liword_t)z)->slot, HCL_OBJ_GET_SIZE(z), shift);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4364,6 +4396,7 @@ hcl_oop_t hcl_strtoint (hcl_t* hcl, const hcl_ooch_t* str, hcl_oow_t len, int ra
|
|||||||
|
|
||||||
if (outlen > HCL_COUNTOF(hw))
|
if (outlen > HCL_COUNTOF(hw))
|
||||||
{
|
{
|
||||||
|
/* TODO: reuse this buffer? */
|
||||||
hwp = (hcl_liw_t*)hcl_allocmem(hcl, outlen * HCL_SIZEOF(hw[0]));
|
hwp = (hcl_liw_t*)hcl_allocmem(hcl, outlen * HCL_SIZEOF(hw[0]));
|
||||||
if (!hwp) return HCL_NULL;
|
if (!hwp) return HCL_NULL;
|
||||||
}
|
}
|
||||||
@ -4441,7 +4474,6 @@ hcl_oop_t hcl_strtoint (hcl_t* hcl, const hcl_ooch_t* str, hcl_oow_t len, int ra
|
|||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
r2 = r1;
|
r2 = r1;
|
||||||
for (i = 0; i < hwlen; i++)
|
for (i = 0; i < hwlen; i++)
|
||||||
{
|
{
|
||||||
@ -4499,7 +4531,7 @@ hcl_oop_t hcl_strtoint (hcl_t* hcl, const hcl_ooch_t* str, hcl_oow_t len, int ra
|
|||||||
|
|
||||||
oops_einval:
|
oops_einval:
|
||||||
if (hwp && hw != hwp) hcl_freemem (hcl, hwp);
|
if (hwp && hw != hwp) hcl_freemem (hcl, hwp);
|
||||||
hcl_seterrnum (hcl, HCL_EINVAL);
|
hcl_seterrbfmt (hcl, HCL_EINVAL, "unable to convert '%.*js' to integer", len, str);
|
||||||
return HCL_NULL;
|
return HCL_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4712,52 +4744,52 @@ hcl_oop_t hcl_sqrtint (hcl_t* hcl, hcl_oop_t x)
|
|||||||
hcl_pushvolat (hcl, &m2);
|
hcl_pushvolat (hcl, &m2);
|
||||||
|
|
||||||
a = hcl_ltints(hcl, x, HCL_SMOOI_TO_OOP(0));
|
a = hcl_ltints(hcl, x, HCL_SMOOI_TO_OOP(0));
|
||||||
if (!a) goto oops;
|
if (HCL_UNLIKELY(!a)) goto oops;
|
||||||
if (a == hcl->_true)
|
if (a == hcl->_true)
|
||||||
{
|
{
|
||||||
/* the given number is a negative number.
|
/* the given number is a negative number.
|
||||||
* i will arrange the return value to be negative. */
|
* i will arrange the return value to be negative. */
|
||||||
x = hcl_negateint(hcl, x);
|
x = hcl_negateint(hcl, x);
|
||||||
if (!x) goto oops;
|
if (HCL_UNLIKELY(!x)) goto oops;
|
||||||
neg = 1;
|
neg = 1;
|
||||||
}
|
}
|
||||||
else neg = 0;
|
else neg = 0;
|
||||||
|
|
||||||
a = HCL_SMOOI_TO_OOP(1);
|
a = HCL_SMOOI_TO_OOP(1);
|
||||||
b = hcl_bitshiftint(hcl, x, HCL_SMOOI_TO_OOP(-5));
|
b = hcl_bitshiftint(hcl, x, HCL_SMOOI_TO_OOP(-5));
|
||||||
if (!b) goto oops;
|
if (HCL_UNLIKELY(!b)) goto oops;
|
||||||
b = hcl_addints(hcl, b, HCL_SMOOI_TO_OOP(8));
|
b = hcl_addints(hcl, b, HCL_SMOOI_TO_OOP(8));
|
||||||
if (!b) goto oops;
|
if (HCL_UNLIKELY(!b)) goto oops;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
t = hcl_geints(hcl, b, a);
|
t = hcl_geints(hcl, b, a);
|
||||||
if (!t) return HCL_NULL;
|
if (HCL_UNLIKELY(!t)) return HCL_NULL;
|
||||||
if (t == hcl->_false) break;
|
if (t == hcl->_false) break;
|
||||||
|
|
||||||
m = hcl_addints(hcl, a, b);
|
m = hcl_addints(hcl, a, b);
|
||||||
if (!m) goto oops;
|
if (HCL_UNLIKELY(!m)) goto oops;
|
||||||
m = hcl_bitshiftint(hcl, m, HCL_SMOOI_TO_OOP(-1));
|
m = hcl_bitshiftint(hcl, m, HCL_SMOOI_TO_OOP(-1));
|
||||||
if (!m) goto oops;
|
if (HCL_UNLIKELY(!m)) goto oops;
|
||||||
m2 = hcl_mulints(hcl, m, m);
|
m2 = hcl_mulints(hcl, m, m);
|
||||||
if (!m2) goto oops;
|
if (HCL_UNLIKELY(!m2)) goto oops;
|
||||||
t = hcl_gtints(hcl, m2, x);
|
t = hcl_gtints(hcl, m2, x);
|
||||||
if (!t) return HCL_NULL;
|
if (HCL_UNLIKELY(!t)) return HCL_NULL;
|
||||||
if (t == hcl->_true)
|
if (t == hcl->_true)
|
||||||
{
|
{
|
||||||
b = hcl_subints(hcl, m, HCL_SMOOI_TO_OOP(1));
|
b = hcl_subints(hcl, m, HCL_SMOOI_TO_OOP(1));
|
||||||
if (!b) goto oops;
|
if (HCL_UNLIKELY(!b)) goto oops;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a = hcl_addints(hcl, m, HCL_SMOOI_TO_OOP(1));
|
a = hcl_addints(hcl, m, HCL_SMOOI_TO_OOP(1));
|
||||||
if (!a) goto oops;
|
if (HCL_UNLIKELY(!a)) goto oops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hcl_popvolats (hcl, 5);
|
hcl_popvolats (hcl, 5);
|
||||||
x = hcl_subints(hcl, a, HCL_SMOOI_TO_OOP(1));
|
x = hcl_subints(hcl, a, HCL_SMOOI_TO_OOP(1));
|
||||||
if (!x) return HCL_NULL;
|
if (HCL_UNLIKELY(!x)) return HCL_NULL;
|
||||||
|
|
||||||
if (neg) x = hcl_negateint(hcl, x);
|
if (neg) x = hcl_negateint(hcl, x);
|
||||||
return x;
|
return x;
|
||||||
@ -4767,7 +4799,6 @@ oops:
|
|||||||
return HCL_NULL;
|
return HCL_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hcl_oop_t hcl_absint (hcl_t* hcl, hcl_oop_t x)
|
hcl_oop_t hcl_absint (hcl_t* hcl, hcl_oop_t x)
|
||||||
{
|
{
|
||||||
if (HCL_OOP_IS_SMOOI(x))
|
if (HCL_OOP_IS_SMOOI(x))
|
||||||
@ -4873,13 +4904,15 @@ hcl_oop_t hcl_inttostr (hcl_t* hcl, hcl_oop_t num, int flagged_radix)
|
|||||||
return hcl_makestring(hcl, xbuf, xlen);
|
return hcl_makestring(hcl, xbuf, xlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* the number can't be represented as a single hcl_oow_t value.
|
||||||
|
* mutli-word conversion begins now */
|
||||||
as = HCL_OBJ_GET_SIZE(num);
|
as = HCL_OBJ_GET_SIZE(num);
|
||||||
|
|
||||||
reqcapa = as * HCL_LIW_BITS + 1;
|
reqcapa = as * HCL_LIW_BITS + 1;
|
||||||
if (hcl->inttostr.xbuf.capa < reqcapa)
|
if (hcl->inttostr.xbuf.capa < reqcapa)
|
||||||
{
|
{
|
||||||
xbuf = (hcl_ooch_t*)hcl_reallocmem(hcl, hcl->inttostr.xbuf.ptr, reqcapa * HCL_SIZEOF(*xbuf));
|
xbuf = (hcl_ooch_t*)hcl_reallocmem(hcl, hcl->inttostr.xbuf.ptr, reqcapa * HCL_SIZEOF(*xbuf));
|
||||||
if (!xbuf) return HCL_NULL;
|
if (HCL_UNLIKELY(!xbuf)) return HCL_NULL;
|
||||||
hcl->inttostr.xbuf.capa = reqcapa;
|
hcl->inttostr.xbuf.capa = reqcapa;
|
||||||
hcl->inttostr.xbuf.ptr = xbuf;
|
hcl->inttostr.xbuf.ptr = xbuf;
|
||||||
}
|
}
|
||||||
@ -4891,7 +4924,7 @@ hcl_oop_t hcl_inttostr (hcl_t* hcl, hcl_oop_t num, int flagged_radix)
|
|||||||
if (hcl->inttostr.t.capa < as)
|
if (hcl->inttostr.t.capa < as)
|
||||||
{
|
{
|
||||||
t = (hcl_liw_t*)hcl_reallocmem(hcl, hcl->inttostr.t.ptr, reqcapa * HCL_SIZEOF(*t));
|
t = (hcl_liw_t*)hcl_reallocmem(hcl, hcl->inttostr.t.ptr, reqcapa * HCL_SIZEOF(*t));
|
||||||
if (!t) return HCL_NULL;
|
if (HCL_UNLIKELY(!t)) return HCL_NULL;
|
||||||
hcl->inttostr.t.capa = as;
|
hcl->inttostr.t.capa = as;
|
||||||
hcl->inttostr.t.ptr = t;
|
hcl->inttostr.t.ptr = t;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user