support ISO extension popcount/1

This commit is contained in:
Vítor Manuel de Morais Santos Costa 2009-10-20 10:03:10 +01:00
parent 90d8b42a85
commit 54465b08f1
3 changed files with 47 additions and 2 deletions

View File

@ -184,6 +184,26 @@ lsb(Int inp) /* calculate the least significant bit for an integer */
return out;
}
static Int
popcount(Int inp) /* calculate the least significant bit for an integer */
{
/* the obvious solution: do it by using binary search */
Int c = 0, j = 0, m = 1L;
if (inp < 0) {
return Yap_ArithError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, MkIntegerTerm(inp),
"popcount/1 received %d", inp);
}
if (inp==0)
return 0L;
for(j=0,c=0; j<sizeof(inp)*8; j++, m<<=1)
{ if ( inp&m )
c++;
}
return c;
}
static Term
eval1(Int fi, Term t) {
arith1_op f = fi;
@ -614,6 +634,25 @@ eval1(Int fi, Term t) {
}
RINT(mpz_scan1(big,0));
}
#endif
case db_ref_e:
RERROR();
}
case op_popcount:
switch (ETypeOfTerm(t)) {
case long_int_e:
RINT(popcount(IntegerOfTerm(t)));
case double_e:
return Yap_ArithError(TYPE_ERROR_INTEGER, t, "popcount(%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,
"popcount/1 received negative bignum");
}
RINT(mpz_popcount(big));
}
#endif
case db_ref_e:
RERROR();
@ -739,6 +778,7 @@ static InitUnEntry InitUnTab[] = {
{"abs", op_abs},
{"msb", op_msb},
{"lsb", op_lsb},
{"popcount", op_popcount},
{"float_fractional_part", op_ffracp},
{"float_integer_part", op_fintp},
{"sign", op_sign},

View File

@ -88,6 +88,7 @@ typedef enum {
op_abs,
op_lsb,
op_msb,
op_popcount,
op_ffracp,
op_fintp,
op_sign,

View File

@ -3900,10 +3900,14 @@ Integer bitwise negation.
The greatest common divisor of the two integers @var{X} and @var{Y}.
@item msb(@var{X})
The most significant bit of the positive integer @var{X}.
The most significant bit of the non-negative integer @var{X}.
@item lsb(@var{X})
The least significant bit of the positive integer @var{X}.
The least significant bit of the non-negative integer @var{X}.
@item popcount(@var{X})
The number of bits set to @code{1} in the binary representation of the
non-negative integer @var{X}.
@item [@var{X}]
Evaluates to @var{X} for expression @var{X}. Useful because character