/*
Copyright (C) 2012 Thomas M. DuBuisson
This file is part of FLINT.
FLINT is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. See .
*/
#include
#include "flint.h"
#include "ulong_extras.h"
#include "fmpz.h"
#ifdef FLINT_USES_POPCNT
static __inline__ flint_bitcnt_t shortCount(slong val)
{
#if defined(_WIN64) || defined(__mips64)
return __builtin_popcountll(val);
#else
return __builtin_popcountl(val);
#endif
}
#else
/* A naive implementation if neither your processor nor your compiler want to
* do the work. */
static __inline__ flint_bitcnt_t shortCount(slong val)
{
flint_bitcnt_t cnt;
for(cnt=0; val; val >>= 1) {
cnt += val & 1;
}
return cnt;
}
#endif
flint_bitcnt_t fmpz_popcnt(const fmpz_t c)
{
fmpz c1;
c1 = *c;
if(!COEFF_IS_MPZ(c1))
{
if(*c < 0) return 0;
else return shortCount(*c);
} else
{
__mpz_struct *t = COEFF_TO_PTR(c1);
if(flint_mpz_cmp_si(t,0) < 0) return 0;
else return mpz_popcount(t);
}
}