added more code for bigint multiplication
This commit is contained in:
parent
b0f8561238
commit
346131b3e3
@ -264,7 +264,8 @@ PROCESS TESTING
|
||||
##((-2305843009213693952 - 10) * (-2305843009213693952 - 10) *(-2305843009213693952 - 10) * (-2305843009213693952 - 10) * 255) dump.
|
||||
|
||||
##(-16rFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF * 1) dump.
|
||||
((-2305843009213693952 * -1) - 1 + 2) dump.
|
||||
##((-2305843009213693952 * -1) - 1 + 2) dump.
|
||||
((-2305843009213693952 * -2305843009213693952 * 2305843009213693952 * 2305843009213693952 * 2305843009213693952) - 1 + 2) dump.
|
||||
"
|
||||
FFI isNil dump.
|
||||
FFI notNil dump.
|
||||
|
@ -67,6 +67,29 @@ static STIX_INLINE int oow_mul_overflow (stix_oow_t a, stix_oow_t b, stix_oow_t*
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (STIX_SIZEOF_OOI_T == STIX_SIZEOF_INT) && defined(STIX_HAVE_BUILTIN_SMUL_OVERFLOW)
|
||||
# define ooi_mul_overflow(a,b,c) __builtin_smul_overflow(a,b,c)
|
||||
#elif (STIX_SIZEOF_OOI_T == STIX_SIZEOF_LONG) && defined(STIX_HAVE_BUILTIN_SMULL_OVERFLOW)
|
||||
# define ooi_mul_overflow(a,b,c) __builtin_smull_overflow(a,b,c)
|
||||
#elif (STIX_SIZEOF_OOI_T == STIX_SIZEOF_LONG_LONG) && defined(STIX_HAVE_BUILTIN_SMULLL_OVERFLOW)
|
||||
# define ooi_mul_overflow(a,b,c) __builtin_smulll_overflow(a,b,c)
|
||||
#else
|
||||
static STIX_INLINE int ooi_mul_overflow (stix_ooi_t a, stix_ooi_t b, stix_ooi_t* c)
|
||||
{
|
||||
#if (STIX_SIZEOF_UINTMAX_T > STIX_SIZEOF_OOI_T)
|
||||
stix_intmax_t k;
|
||||
k = (stix_intmax_t)a * (stix_intmax_t)b;
|
||||
*c = (stix_ooi_t)k;
|
||||
return k > STIX_TYPE_MAX(stix_ooi_t) || k < STIX_TYPE_MIN(stix_ooi_t);
|
||||
#else
|
||||
/* TODO: fix this */
|
||||
#error not implemented
|
||||
*c = a * b;
|
||||
return b > 0 && a > STIX_TYPE_MAX(stix_ooi_t) / b; /* works for unsigned types only */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (SIZEOF_ATOM_T == STIX_SIZEOF_INT) && defined(STIX_HAVE_BUILTIN_UADD_OVERFLOW)
|
||||
# define atom_add_overflow(a,b,c) __builtin_uadd_overflow(a,b,c)
|
||||
#elif (SIZEOF_ATOM_T == STIX_SIZEOF_LONG) && defined(STIX_HAVE_BUILTIN_UADDL_OVERFLOW)
|
||||
@ -158,12 +181,12 @@ static STIX_INLINE stix_oop_t make_bigint_with_ooi (stix_t* stix, stix_ooi_t i)
|
||||
|
||||
static STIX_INLINE stix_oop_t make_bigint_with_intmax (stix_t* stix, stix_intmax_t v)
|
||||
{
|
||||
/* this is not a generic function. it can't handle v
|
||||
* if it's STIX_TYPE_MIN(stix_intmax_t) */
|
||||
stix_oow_t len;
|
||||
atom_t buf[STIX_SIZEOF_INTMAX_T / SIZEOF_ATOM_T];
|
||||
stix_uintmax_t ui;
|
||||
|
||||
/* this is not a generic function. it can't handle v
|
||||
* if it's STIX_TYPE_MIN(stix_intmax_t) */
|
||||
STIX_ASSERT (v > STIX_TYPE_MIN(stix_intmax_t));
|
||||
|
||||
ui = (v >= 0)? v: -v;
|
||||
@ -175,6 +198,15 @@ static STIX_INLINE stix_oop_t make_bigint_with_intmax (stix_t* stix, stix_intmax
|
||||
}
|
||||
while (ui > 0);
|
||||
|
||||
{ int i;
|
||||
printf ("MKBI-INTMAX=>");
|
||||
for (i = len; i > 0;)
|
||||
{
|
||||
printf ("%016lX ", (unsigned long)buf[--i]);
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
return stix_instantiate (stix, ((v >= 0)? stix->_large_positive_integer: stix->_large_negative_integer), buf, len);
|
||||
}
|
||||
|
||||
@ -747,19 +779,42 @@ stix_oop_t stix_mulints (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||
|
||||
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
|
||||
{
|
||||
#if STIX_SIZEOF_INTMAX_T > STIX_SIZEOF_OOI_T
|
||||
/*#if STIX_SIZEOF_INTMAX_T > STIX_SIZEOF_OOI_T*/ /* TOOD: uncomment this line and remove the next line after #else block has been tested */
|
||||
#if STIX_SIZEOF_INTMAX_T <= STIX_SIZEOF_OOI_T
|
||||
stix_intmax_t i;
|
||||
|
||||
i = (stix_intmax_t)STIX_OOP_TO_SMOOI(x) * (stix_intmax_t)STIX_OOP_TO_SMOOI(y);
|
||||
if (STIX_IN_SMOOI_RANGE(i)) return STIX_SMOOI_TO_OOP((stix_ooi_t)i);
|
||||
|
||||
return make_bigint_with_intmax (stix, i);
|
||||
#else
|
||||
stix_ooi_t i;
|
||||
stix_ooi_t xv, yv;
|
||||
|
||||
xv = STIX_OOP_TO_SMOOI(x);
|
||||
yv = STIX_OOP_TO_SMOOI(y);
|
||||
if (ooi_mul_overflow (xv, yv, &i))
|
||||
{
|
||||
/* overflowed
|
||||
* -----------------------------------------------------
|
||||
* no need to call stix_pushtmp() on x and y as they are
|
||||
* known to be small integers and we don't need them.
|
||||
* actual values are all in xv and yv. */
|
||||
if (!(x = make_bigint_with_ooi (stix, xv)) ||
|
||||
!(y = make_bigint_with_ooi (stix, yv))) return STIX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (STIX_IN_SMOOI_RANGE(i)) return STIX_SMOOI_TO_OOP(i);
|
||||
return make_bigint_with_ooi (stix, i);
|
||||
}
|
||||
|
||||
/*
|
||||
stix_ooi_t i;
|
||||
|
||||
i = STIX_OOP_TO_SMOOI(x) * STIX_OOP_TO_SMOOI(y);
|
||||
if (STIX_IN_SMOOI_RANGE(i)) return STIX_SMOOI_TO_OOP(i);
|
||||
|
||||
return make_bigint_with_ooi (stix, i);
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
@ -544,6 +544,7 @@ typedef stix_ucs_t stix_oocs_t;
|
||||
#if __has_builtin(__builtin_ctz)
|
||||
#define STIX_HAVE_BUILTIN_CTZ
|
||||
#endif
|
||||
|
||||
#if __has_builtin(__builtin_uadd_overflow)
|
||||
#define STIX_HAVE_BUILTIN_UADD_OVERFLOW
|
||||
#endif
|
||||
@ -562,9 +563,31 @@ typedef stix_ucs_t stix_oocs_t;
|
||||
#if __has_builtin(__builtin_umulll_overflow)
|
||||
#define STIX_HAVE_BUILTIN_UMULLL_OVERFLOW
|
||||
#endif
|
||||
|
||||
|
||||
#if __has_builtin(__builtin_sadd_overflow)
|
||||
#define STIX_HAVE_BUILTIN_SADD_OVERFLOW
|
||||
#endif
|
||||
#if __has_builtin(__builtin_saddl_overflow)
|
||||
#define STIX_HAVE_BUILTIN_SADDL_OVERFLOW
|
||||
#endif
|
||||
#if __has_builtin(__builtin_saddll_overflow)
|
||||
#define STIX_HAVE_BUILTIN_SADDLL_OVERFLOW
|
||||
#endif
|
||||
#if __has_builtin(__builtin_smul_overflow)
|
||||
#define STIX_HAVE_BUILTIN_SMUL_OVERFLOW
|
||||
#endif
|
||||
#if __has_builtin(__builtin_smull_overflow)
|
||||
#define STIX_HAVE_BUILTIN_SMULL_OVERFLOW
|
||||
#endif
|
||||
#if __has_builtin(__builtin_smulll_overflow)
|
||||
#define STIX_HAVE_BUILTIN_SMULLL_OVERFLOW
|
||||
#endif
|
||||
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
|
||||
|
||||
#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
#define STIX_HAVE_BUILTIN_CTZ
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ >= 5)
|
||||
#define STIX_HAVE_BUILTIN_UADD_OVERFLOW
|
||||
#define STIX_HAVE_BUILTIN_UADDL_OVERFLOW
|
||||
@ -572,11 +595,15 @@ typedef stix_ucs_t stix_oocs_t;
|
||||
#define STIX_HAVE_BUILTIN_UMUL_OVERFLOW
|
||||
#define STIX_HAVE_BUILTIN_UMULL_OVERFLOW
|
||||
#define STIX_HAVE_BUILTIN_UMULLL_OVERFLOW
|
||||
|
||||
#define STIX_HAVE_BUILTIN_SADD_OVERFLOW
|
||||
#define STIX_HAVE_BUILTIN_SADDL_OVERFLOW
|
||||
#define STIX_HAVE_BUILTIN_SADDLL_OVERFLOW
|
||||
#define STIX_HAVE_BUILTIN_SMUL_OVERFLOW
|
||||
#define STIX_HAVE_BUILTIN_SMULL_OVERFLOW
|
||||
#define STIX_HAVE_BUILTIN_SMULLL_OVERFLOW
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
#define STIX_HAVE_BUILTIN_CTZ
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -92,9 +92,10 @@ typedef struct stix_obj_byte_t* stix_oop_byte_t;
|
||||
typedef struct stix_obj_halfword_t* stix_oop_halfword_t;
|
||||
typedef struct stix_obj_word_t* stix_oop_word_t;
|
||||
|
||||
#define STIX_OOW_BITS (STIX_SIZEOF(stix_oow_t) * 8)
|
||||
#define STIX_OOP_BITS (STIX_SIZEOF(stix_oop_t) * 8)
|
||||
#define STIX_OOHW_BITS (STIX_SIZEOF(stix_oohw_t) * 8)
|
||||
#define STIX_OOW_BITS (STIX_SIZEOF_OOW_T * 8)
|
||||
#define STIX_OOI_BITS (STIX_SIZEOF_OOI_T * 8)
|
||||
#define STIX_OOP_BITS (STIX_SIZEOF_OOP_T * 8)
|
||||
#define STIX_OOHW_BITS (STIX_SIZEOF_OOHW_T * 8)
|
||||
|
||||
/*
|
||||
* OOP encoding
|
||||
|
Loading…
Reference in New Issue
Block a user