added some more bigint routines
This commit is contained in:
@ -28,6 +28,9 @@
|
||||
|
||||
#define MAKE_WORD(hw1,hw2) ((stix_oow_t)(hw1) | (stix_oow_t)(hw2) << STIX_OOHW_BITS)
|
||||
|
||||
/*#define IS_POWER_OF_2(ui) (((ui) > 0) && (((ui) & (~(ui)+ 1)) == (ui)))*/
|
||||
#define IS_POWER_OF_2(ui) (((ui) > 0) && ((ui) & ((ui) - 1)) == 0) /* unsigned integer only */
|
||||
|
||||
static STIX_INLINE int is_integer (stix_t* stix, stix_oop_t oop)
|
||||
{
|
||||
stix_oop_t c;
|
||||
@ -465,3 +468,142 @@ oops_einval:
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
stix_oop_t stix_strtoint (stix_t* stix, const stix_ooch_t* str, stix_oow_t len, unsigned int radix)
|
||||
{
|
||||
int neg = 0;
|
||||
const stix_ooch_t* ptr, * start, * end;
|
||||
stix_oow_t w, v, r;
|
||||
stix_oohw_t hw[64];
|
||||
stix_oow_t hwlen;
|
||||
|
||||
STIX_ASSERT (radix >= 2 && radix <= 36);
|
||||
|
||||
ptr = str;
|
||||
end = str + len;
|
||||
|
||||
if (ptr < end)
|
||||
{
|
||||
if (*ptr == '+') ptr++;
|
||||
else if (*ptr == '-')
|
||||
{
|
||||
ptr++;
|
||||
neg = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr >= end) goto oops_einval; /* no digits */
|
||||
|
||||
while (ptr < end && *ptr == '0')
|
||||
{
|
||||
/* skip leading zeros */
|
||||
ptr++;
|
||||
}
|
||||
if (ptr >= end)
|
||||
{
|
||||
/* all zeros */
|
||||
return STIX_OOP_FROM_SMINT(0);
|
||||
}
|
||||
|
||||
if (IS_POWER_OF_2(radix))
|
||||
{
|
||||
unsigned int exp;
|
||||
|
||||
/* get log2(radix) in a fast way under the fact that
|
||||
* radix is a power of 2. */
|
||||
#if defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
|
||||
/* use the Bit Scan Forward instruction */
|
||||
__asm__ volatile (
|
||||
"bsf %1,%0\n\t"
|
||||
: "=&r"(exp) /* output */
|
||||
: "r"(radix) /* input */
|
||||
);
|
||||
|
||||
#elif defined(__GNUC__) && defined(__arm__)
|
||||
|
||||
__asm__ volatile (
|
||||
"clz %0,%1\n\t"
|
||||
: "=&r"(exp) /* output */
|
||||
: "r"(radix) /* input */
|
||||
|
||||
/* TODO: ARM - use clz, PPC - use cntlz, cntlzw, cntlzd, SPARC - use lzcnt, MIPS clz */
|
||||
#else
|
||||
static unsigned int exp_tab[] =
|
||||
{
|
||||
0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0
|
||||
};
|
||||
exp = exp_tab[radix];
|
||||
#endif
|
||||
|
||||
start = ptr; /* this is the real start */
|
||||
ptr = end - 1;
|
||||
|
||||
hwlen = 0;
|
||||
w = 0;
|
||||
r = 1;
|
||||
while (ptr >= start)
|
||||
{
|
||||
if (*ptr >= '0' && *ptr <= '9') v = *ptr - '0';
|
||||
else if (*ptr >= 'A' && *ptr <= 'Z') v = *ptr - 'A' + 10;
|
||||
else if (*ptr >= 'a' && *ptr <= 'z') v = *ptr - 'a' + 10;
|
||||
else goto oops_einval;
|
||||
|
||||
if (v >= radix) goto oops_einval;
|
||||
|
||||
printf ("wwww=<<%lx>>", (long int)w);
|
||||
w += v * r;
|
||||
printf ("r=><<%lX>> v<<%lX>> w<<%lX>>\n", (long int)r, (long int)v, (long int)w);
|
||||
if (w > STIX_TYPE_MAX(stix_oohw_t))
|
||||
{
|
||||
hw[hwlen++] = (stix_oohw_t)(w & STIX_LBMASK(stix_oow_t, STIX_OOHW_BITS));
|
||||
w = w >> STIX_OOHW_BITS;
|
||||
if (w == 0) r = 1;
|
||||
else r = radix;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = r * radix;
|
||||
}
|
||||
|
||||
ptr--;
|
||||
}
|
||||
|
||||
STIX_ASSERT (w <= STIX_TYPE_MAX(stix_oohw_t));
|
||||
hw[hwlen++] = w;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
|
||||
}
|
||||
|
||||
/*
|
||||
if (hwlen == 1) return STIX_OOP_FROM_SMINT((stix_ooi_t)hw[0] * -neg);
|
||||
else if (hwlen == 2)
|
||||
{
|
||||
w = MAKE_WORD(hw[0], hw[1]);
|
||||
if (neg)
|
||||
{
|
||||
if (w <= STIX_SMINT_MAX + 1) return STIX_OOP_FROM_SMINT(-(stix_ooi_t)w);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (w <= STIX_SMINT_MAX) return STIX_OOP_FROM_SMINT(w);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
{ int i;
|
||||
for (i = hwlen; i > 0;)
|
||||
{
|
||||
printf ("%x ", hw[--i]);
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
return stix_instantiate (stix, (neg? stix->_large_negative_integer: stix->_large_positive_integer), hw, hwlen);
|
||||
|
||||
oops_einval:
|
||||
stix->errnum = STIX_EINVAL;
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
@ -434,6 +434,10 @@ int main (int argc, char* argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
stix_oow_t tab_size;
|
||||
|
||||
@ -457,6 +461,20 @@ int main (int argc, char* argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
|
||||
/*const stix_bch_t* xxx = "9999999999999999999999999999999999999999999999999999999999999999999999999999999999";*/
|
||||
const stix_bch_t* xxx = "7777777777777777777777777";
|
||||
stix_ooch_t buf[10240];
|
||||
stix_oow_t xxxlen;
|
||||
stix_oow_t buflen;
|
||||
|
||||
xxxlen = stix_countbcstr(xxx);
|
||||
buflen = STIX_COUNTOF(buf);
|
||||
stix_utf8toucs (xxx, &xxxlen, buf, &buflen);
|
||||
stix_strtoint (stix, buf, buflen, 16);
|
||||
}
|
||||
{
|
||||
stix_ooch_t x[] = { 'X', 't', 'r', 'i', 'n', 'g', '\0' };
|
||||
stix_ooch_t y[] = { 'S', 'y', 'm', 'b', 'o', 'l', '\0' };
|
||||
|
@ -439,6 +439,38 @@ struct stix_cmgr_t
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The STIX_TYPE_IS_SIGNED() macro determines if a type is signed.
|
||||
* \code
|
||||
* printf ("%d\n", (int)STIX_TYPE_IS_SIGNED(int));
|
||||
* printf ("%d\n", (int)STIX_TYPE_IS_SIGNED(unsigned int));
|
||||
* \endcode
|
||||
*/
|
||||
#define STIX_TYPE_IS_SIGNED(type) (((type)0) > ((type)-1))
|
||||
|
||||
/**
|
||||
* The STIX_TYPE_IS_SIGNED() macro determines if a type is unsigned.
|
||||
* \code
|
||||
* printf ("%d\n", STIX_TYPE_IS_UNSIGNED(int));
|
||||
* printf ("%d\n", STIX_TYPE_IS_UNSIGNED(unsigned int));
|
||||
* \endcode
|
||||
*/
|
||||
#define STIX_TYPE_IS_UNSIGNED(type) (((type)0) < ((type)-1))
|
||||
|
||||
#define STIX_TYPE_SIGNED_MAX(type) \
|
||||
((type)~((type)1 << (STIX_SIZEOF(type) * 8 - 1)))
|
||||
#define STIX_TYPE_UNSIGNED_MAX(type) ((type)(~(type)0))
|
||||
|
||||
#define STIX_TYPE_SIGNED_MIN(type) \
|
||||
((type)((type)1 << (STIX_SIZEOF(type) * 8 - 1)))
|
||||
#define STIX_TYPE_UNSIGNED_MIN(type) ((type)0)
|
||||
|
||||
#define STIX_TYPE_MAX(type) \
|
||||
((STIX_TYPE_IS_SIGNED(type)? STIX_TYPE_SIGNED_MAX(type): STIX_TYPE_UNSIGNED_MAX(type)))
|
||||
#define STIX_TYPE_MIN(type) \
|
||||
((STIX_TYPE_IS_SIGNED(type)? STIX_TYPE_SIGNED_MIN(type): STIX_TYPE_UNSIGNED_MIN(type)))
|
||||
|
||||
|
||||
/* =========================================================================
|
||||
* BASIC STIX TYPES
|
||||
* =========================================================================*/
|
||||
|
@ -147,6 +147,20 @@ stix_size_t stix_copybcstr (stix_bch_t* dst, stix_size_t len, const stix_bch_t*
|
||||
return p - dst;
|
||||
}
|
||||
|
||||
stix_size_t stix_countucstr (const stix_uch_t* str)
|
||||
{
|
||||
const stix_uch_t* ptr = str;
|
||||
while (*ptr != '\0') ptr++;
|
||||
return ptr - str;
|
||||
}
|
||||
|
||||
stix_size_t stix_countbcstr (const stix_bch_t* str)
|
||||
{
|
||||
const stix_bch_t* ptr = str;
|
||||
while (*ptr != '\0') ptr++;
|
||||
return ptr - str;
|
||||
}
|
||||
|
||||
stix_uch_t* stix_finduchar (const stix_uch_t* ptr, stix_size_t len, stix_uch_t c)
|
||||
{
|
||||
const stix_uch_t* end;
|
||||
@ -161,7 +175,7 @@ stix_uch_t* stix_finduchar (const stix_uch_t* ptr, stix_size_t len, stix_uch_t c
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
stix_uch_t* stix_findbchar (const stix_bch_t* ptr, stix_size_t len, stix_bch_t c)
|
||||
stix_bch_t* stix_findbchar (const stix_bch_t* ptr, stix_size_t len, stix_bch_t c)
|
||||
{
|
||||
const stix_bch_t* end;
|
||||
|
||||
|
@ -41,6 +41,7 @@ extern "C" {
|
||||
# define stix_copybchtooochars(dst,src,len) stix_copybchtouchars(dst,src,len)
|
||||
# define stix_copyoocstr(dst,len,src) stix_copyucstr(dst,len,src)
|
||||
# define stix_findoochar(ptr,len,c) stix_finduchar(ptr,len,c)
|
||||
# define stix_countoocstr(str) stix_countucstr(str)
|
||||
#else
|
||||
# define stix_hashchars(ptr,len) stix_hashbchars(ptr,len)
|
||||
# define stix_compoocbcstr(str1,str2) stix_compbcstr(str1,str2)
|
||||
@ -49,6 +50,7 @@ extern "C" {
|
||||
# define stix_copybchtooochars(dst,src,len) stix_copybchars(dst,src,len)
|
||||
# define stix_copyoocstr(dst,len,src) stix_copybcstr(dst,len,src)
|
||||
# define stix_findoochar(ptr,len,c) stix_findbchar(ptr,len,c)
|
||||
# define stix_countoocstr(str) stix_countbcstr(str)
|
||||
#endif
|
||||
|
||||
|
||||
@ -113,18 +115,6 @@ void stix_copybchtouchars (
|
||||
stix_size_t len
|
||||
);
|
||||
|
||||
stix_uch_t* stix_finduchar (
|
||||
const stix_uch_t* ptr,
|
||||
stix_size_t len,
|
||||
stix_uch_t c
|
||||
);
|
||||
|
||||
stix_uch_t* stix_findbchar (
|
||||
const stix_bch_t* ptr,
|
||||
stix_size_t len,
|
||||
stix_bch_t c
|
||||
);
|
||||
|
||||
stix_size_t stix_copyucstr (
|
||||
stix_uch_t* dst,
|
||||
stix_size_t len,
|
||||
@ -137,6 +127,25 @@ stix_size_t stix_copybcstr (
|
||||
const stix_bch_t* src
|
||||
);
|
||||
|
||||
stix_uch_t* stix_finduchar (
|
||||
const stix_uch_t* ptr,
|
||||
stix_size_t len,
|
||||
stix_uch_t c
|
||||
);
|
||||
|
||||
stix_bch_t* stix_findbchar (
|
||||
const stix_bch_t* ptr,
|
||||
stix_size_t len,
|
||||
stix_bch_t c
|
||||
);
|
||||
|
||||
stix_size_t stix_countucstr (
|
||||
const stix_uch_t* str
|
||||
);
|
||||
|
||||
stix_size_t stix_countbcstr (
|
||||
const stix_bch_t* str
|
||||
);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
Reference in New Issue
Block a user