added some more bigint routines

This commit is contained in:
hyunghwan.chung
2015-11-03 14:08:43 +00:00
parent 730df12933
commit e061b94832
10 changed files with 228 additions and 33290 deletions

View File

@ -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;
}

View File

@ -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' };

View File

@ -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
* =========================================================================*/

View File

@ -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;

View File

@ -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)
}