support for msb
This commit is contained in:
parent
d18cb214fa
commit
36e0c6bcf7
52
C/arith1.c
52
C/arith1.c
@ -160,6 +160,30 @@ msb(Int inp) /* calculate the most significant bit for an integer */
|
|||||||
return(out);
|
return(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Int
|
||||||
|
lsb(Int inp) /* calculate the least significant bit for an integer */
|
||||||
|
{
|
||||||
|
/* the obvious solution: do it by using binary search */
|
||||||
|
Int out = 0;
|
||||||
|
|
||||||
|
if (inp < 0) {
|
||||||
|
return Yap_ArithError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, MkIntegerTerm(inp),
|
||||||
|
"msb/1 received %d", inp);
|
||||||
|
}
|
||||||
|
if (inp==0)
|
||||||
|
return 0L;
|
||||||
|
#if SIZEOF_LONG_INT == 8
|
||||||
|
if (!(inp & 0xffffffffLL)) {inp >>= 32; out += 32;}
|
||||||
|
#endif
|
||||||
|
if (!(inp & 0xffffL)) {inp >>= 16; out += 16;}
|
||||||
|
if (!(inp & 0xffL)) {inp >>= 8; out += 8;}
|
||||||
|
if (!(inp & 0xfL)) {inp >>= 4; out += 4;}
|
||||||
|
if (!(inp & 0x3L)) {inp >>= 2; out += 2;}
|
||||||
|
if (!(inp & 0x1L)) out++;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
static Term
|
static Term
|
||||||
eval1(Int fi, Term t) {
|
eval1(Int fi, Term t) {
|
||||||
arith1_op f = fi;
|
arith1_op f = fi;
|
||||||
@ -564,7 +588,32 @@ eval1(Int fi, Term t) {
|
|||||||
return Yap_ArithError(TYPE_ERROR_INTEGER, t, "msb(%f)", FloatOfTerm(t));
|
return Yap_ArithError(TYPE_ERROR_INTEGER, t, "msb(%f)", FloatOfTerm(t));
|
||||||
case big_int_e:
|
case big_int_e:
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
RINT(mpz_sizeinbase(Yap_BigIntOfTerm(t),2));
|
{ MP_INT *big = Yap_BigIntOfTerm(t);
|
||||||
|
if ( mpz_sgn(big) <= 0 ) {
|
||||||
|
return Yap_ArithError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t,
|
||||||
|
"msb/1 received bignum");
|
||||||
|
}
|
||||||
|
RINT(mpz_sizeinbase(big,2));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
case db_ref_e:
|
||||||
|
RERROR();
|
||||||
|
}
|
||||||
|
case op_lsb:
|
||||||
|
switch (ETypeOfTerm(t)) {
|
||||||
|
case long_int_e:
|
||||||
|
RINT(lsb(IntegerOfTerm(t)));
|
||||||
|
case double_e:
|
||||||
|
return Yap_ArithError(TYPE_ERROR_INTEGER, t, "lsb(%f)", FloatOfTerm(t));
|
||||||
|
case big_int_e:
|
||||||
|
#ifdef USE_GMP
|
||||||
|
{ MP_INT *big = Yap_BigIntOfTerm(t);
|
||||||
|
if ( mpz_sgn(big) <= 0 ) {
|
||||||
|
return Yap_ArithError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t,
|
||||||
|
"lsb/1 received bignum");
|
||||||
|
}
|
||||||
|
RINT(mpz_scan1(big,0));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
case db_ref_e:
|
case db_ref_e:
|
||||||
RERROR();
|
RERROR();
|
||||||
@ -689,6 +738,7 @@ static InitUnEntry InitUnTab[] = {
|
|||||||
{"float", op_float},
|
{"float", op_float},
|
||||||
{"abs", op_abs},
|
{"abs", op_abs},
|
||||||
{"msb", op_msb},
|
{"msb", op_msb},
|
||||||
|
{"lsb", op_lsb},
|
||||||
{"float_fractional_part", op_ffracp},
|
{"float_fractional_part", op_ffracp},
|
||||||
{"float_integer_part", op_fintp},
|
{"float_integer_part", op_fintp},
|
||||||
{"sign", op_sign},
|
{"sign", op_sign},
|
||||||
|
Reference in New Issue
Block a user