support ISO extension popcount/1
This commit is contained in:
parent
90d8b42a85
commit
54465b08f1
40
C/arith1.c
40
C/arith1.c
@ -184,6 +184,26 @@ lsb(Int inp) /* calculate the least significant bit for an integer */
|
|||||||
return out;
|
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
|
static Term
|
||||||
eval1(Int fi, Term t) {
|
eval1(Int fi, Term t) {
|
||||||
arith1_op f = fi;
|
arith1_op f = fi;
|
||||||
@ -614,6 +634,25 @@ eval1(Int fi, Term t) {
|
|||||||
}
|
}
|
||||||
RINT(mpz_scan1(big,0));
|
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
|
#endif
|
||||||
case db_ref_e:
|
case db_ref_e:
|
||||||
RERROR();
|
RERROR();
|
||||||
@ -739,6 +778,7 @@ static InitUnEntry InitUnTab[] = {
|
|||||||
{"abs", op_abs},
|
{"abs", op_abs},
|
||||||
{"msb", op_msb},
|
{"msb", op_msb},
|
||||||
{"lsb", op_lsb},
|
{"lsb", op_lsb},
|
||||||
|
{"popcount", op_popcount},
|
||||||
{"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},
|
||||||
|
1
H/eval.h
1
H/eval.h
@ -88,6 +88,7 @@ typedef enum {
|
|||||||
op_abs,
|
op_abs,
|
||||||
op_lsb,
|
op_lsb,
|
||||||
op_msb,
|
op_msb,
|
||||||
|
op_popcount,
|
||||||
op_ffracp,
|
op_ffracp,
|
||||||
op_fintp,
|
op_fintp,
|
||||||
op_sign,
|
op_sign,
|
||||||
|
@ -3900,10 +3900,14 @@ Integer bitwise negation.
|
|||||||
The greatest common divisor of the two integers @var{X} and @var{Y}.
|
The greatest common divisor of the two integers @var{X} and @var{Y}.
|
||||||
|
|
||||||
@item msb(@var{X})
|
@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})
|
@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}]
|
@item [@var{X}]
|
||||||
Evaluates to @var{X} for expression @var{X}. Useful because character
|
Evaluates to @var{X} for expression @var{X}. Useful because character
|
||||||
|
Reference in New Issue
Block a user