added moo_inttouintmax and moo_inttointmax
This commit is contained in:
		
							
								
								
									
										117
									
								
								moo/lib/bigint.c
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								moo/lib/bigint.c
									
									
									
									
									
								
							@ -374,7 +374,7 @@ int moo_inttoooi (moo_t* moo, moo_oop_t x, moo_ooi_t* i)
 | 
			
		||||
	n = moo_inttooow(moo, x, &w);
 | 
			
		||||
	if (n < 0) 
 | 
			
		||||
	{
 | 
			
		||||
		MOO_ASSERT (moo, MOO_TYPE_MAX(moo_ooi_t) + MOO_TYPE_MIN(moo_ooi_t) == -1); /* assume 2's complement */
 | 
			
		||||
		MOO_STATIC_ASSERT (MOO_TYPE_MAX(moo_ooi_t) + MOO_TYPE_MIN(moo_ooi_t) == -1); /* assume 2's complement */
 | 
			
		||||
		if (w > (moo_oow_t)MOO_TYPE_MAX(moo_ooi_t) + 1)
 | 
			
		||||
		{
 | 
			
		||||
			moo_seterrnum (moo, MOO_ERANGE); /* not convertable. number too small */
 | 
			
		||||
@ -395,6 +395,121 @@ int moo_inttoooi (moo_t* moo, moo_oop_t x, moo_ooi_t* i)
 | 
			
		||||
	return n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if (MOO_SIZEOF_UINTMAX_T == MOO_SIZEOF_OOW_T)
 | 
			
		||||
 | 
			
		||||
	/* do nothing. required macros are defined in moo.h */
 | 
			
		||||
 | 
			
		||||
#elif (MOO_SIZEOF_UINTMAX_T == MOO_SIZEOF_OOW_T * 2)
 | 
			
		||||
static MOO_INLINE int bigint_to_uintmax (moo_t* moo, moo_oop_t num, moo_uintmax_t* w)
 | 
			
		||||
{
 | 
			
		||||
	MOO_ASSERT (moo, MOO_OOP_IS_POINTER(num));
 | 
			
		||||
	MOO_ASSERT (moo, MOO_POINTER_IS_PBIGINT(moo, num) || MOO_POINTER_IS_NBIGINT(moo, num));
 | 
			
		||||
 | 
			
		||||
#if (MOO_LIW_BITS == MOO_OOW_BITS)
 | 
			
		||||
	MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(num) >= 1);
 | 
			
		||||
 | 
			
		||||
	switch (MOO_OBJ_GET_SIZE(num))
 | 
			
		||||
	{
 | 
			
		||||
		case 1:
 | 
			
		||||
			*w = ((moo_uintmax_t)MOO_OBJ_GET_WORD_SLOT(num)[0];
 | 
			
		||||
			goto done;
 | 
			
		||||
 | 
			
		||||
		case 2:
 | 
			
		||||
			*w = ((moo_uintmax_t)MOO_OBJ_GET_WORD_SLOT(num)[0] << MOO_LIW_BITS) | MOO_OBJ_GET_WORD_SLOT(num)[1];
 | 
			
		||||
			goto done;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			goto oops_range;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#elif (MOO_LIW_BITS == MOO_OOHW_BITS)
 | 
			
		||||
	MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(num) >= 2);
 | 
			
		||||
	switch (MOO_OBJ_GET_SIZE(num))
 | 
			
		||||
	{
 | 
			
		||||
		case 2:
 | 
			
		||||
			*w = ((moo_uintmax_t)MOO_OBJ_GET_HALFWORD_SLOT(num)[0] << MOO_LIW_BITS) | MOO_OBJ_GET_HALFWORD_SLOT(num)[1];
 | 
			
		||||
			goto done;
 | 
			
		||||
 | 
			
		||||
		case 4:
 | 
			
		||||
			*w = ((moo_uintmax_t)MOO_OBJ_GET_HALFWORD_SLOT(num)[0] << MOO_LIW_BITS * 3) | 
 | 
			
		||||
			     ((moo_uintmax_t)MOO_OBJ_GET_HALFWORD_SLOT(num)[1] << MOO_LIW_BITS * 2) |
 | 
			
		||||
			     ((moo_uintmax_t)MOO_OBJ_GET_HALFWORD_SLOT(num)[2] << MOO_LIW_BITS * 1) |
 | 
			
		||||
			     MOO_OBJ_GET_HALFWORD_SLOT(num)[3];
 | 
			
		||||
			goto done;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			goto oops_range;
 | 
			
		||||
	}
 | 
			
		||||
#else
 | 
			
		||||
#	error UNSUPPORTED LIW BIT SIZE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
done:
 | 
			
		||||
	return (MOO_POINTER_IS_NBIGINT(moo, num))? -1: 1;
 | 
			
		||||
 | 
			
		||||
oops_range:
 | 
			
		||||
	moo_seterrnum (moo, MOO_ERANGE);
 | 
			
		||||
	return 0; /* not convertable */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int moo_inttouintmax (moo_t* moo, moo_oop_t x, moo_uintmax_t* w)
 | 
			
		||||
{
 | 
			
		||||
	if (MOO_OOP_IS_SMOOI(x))
 | 
			
		||||
	{
 | 
			
		||||
		moo_ooi_t v;
 | 
			
		||||
 | 
			
		||||
		v = MOO_OOP_TO_SMOOI(x);
 | 
			
		||||
		if (v < 0)
 | 
			
		||||
		{
 | 
			
		||||
			*w = -v;
 | 
			
		||||
			return -1; /* negative number negated - kind of an error */
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			*w = v;
 | 
			
		||||
			return 1; /* zero or positive number */
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (moo_isbigint(moo, x)) return bigint_to_uintmax(moo, x, w);
 | 
			
		||||
 | 
			
		||||
	moo_seterrbfmt (moo, MOO_EINVAL, "not an integer - %O", x);
 | 
			
		||||
	return 0; /* not convertable - too big, too small, or not an integer */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int moo_inttointmax (moo_t* moo, moo_oop_t x, moo_intmax_t* i)
 | 
			
		||||
{
 | 
			
		||||
	moo_uintmax_t w;
 | 
			
		||||
	int n;
 | 
			
		||||
 | 
			
		||||
	n = moo_inttouintmax(moo, x, &w);
 | 
			
		||||
	if (n < 0) 
 | 
			
		||||
	{
 | 
			
		||||
		MOO_STATIC_ASSERT (MOO_TYPE_MAX(moo_intmax_t) + MOO_TYPE_MIN(moo_intmax_t) == -1); /* assume 2's complement */
 | 
			
		||||
		if (w > (moo_uintmax_t)MOO_TYPE_MAX(moo_intmax_t) + 1)
 | 
			
		||||
		{
 | 
			
		||||
			moo_seterrnum (moo, MOO_ERANGE); /* not convertable. number too small */
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		*i = -w;
 | 
			
		||||
	}
 | 
			
		||||
	else if (n > 0) 
 | 
			
		||||
	{
 | 
			
		||||
		if (w > MOO_TYPE_MAX(moo_intmax_t)) 
 | 
			
		||||
		{
 | 
			
		||||
			moo_seterrnum (moo, MOO_ERANGE); /* not convertable. number too big */
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		*i = w;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
#	error UNSUPPORTED UINTMAX SIZE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static MOO_INLINE moo_oop_t make_bigint_with_oow (moo_t* moo, moo_oow_t w)
 | 
			
		||||
{
 | 
			
		||||
#if (MOO_LIW_BITS == MOO_OOW_BITS)
 | 
			
		||||
 | 
			
		||||
@ -2208,6 +2208,23 @@ MOO_EXPORT int moo_inttoooi (
 | 
			
		||||
	moo_ooi_t* i
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
#if (MOO_SIZEOF_UINTMAX_T == MOO_SIZEOF_OOW_T)
 | 
			
		||||
#	define moo_inttouintmax moo_inttooow
 | 
			
		||||
#	define moo_inttointmax moo_inttoooi
 | 
			
		||||
#else
 | 
			
		||||
MOO_EXPORT int moo_inttouintmax (
 | 
			
		||||
	moo_t*         moo,
 | 
			
		||||
	moo_oop_t      x,
 | 
			
		||||
	moo_uintmax_t* w
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
MOO_EXPORT int moo_inttointmax (
 | 
			
		||||
	moo_t*        moo,
 | 
			
		||||
	moo_oop_t     x,
 | 
			
		||||
	moo_intmax_t* i
 | 
			
		||||
);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
MOO_EXPORT moo_oop_t moo_findclass (
 | 
			
		||||
	moo_t*            moo,
 | 
			
		||||
	moo_oop_nsdic_t   nsdic,
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user