|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* (C) 2001 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#if !defined(MPL_MATH_H_INCLUDED)
|
|
Packit Service |
c5cf8c |
#define MPL_MATH_H_INCLUDED
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* *INDENT-ON* */
|
|
Packit Service |
c5cf8c |
#if defined(__cplusplus)
|
|
Packit Service |
c5cf8c |
extern "C" {
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
/* *INDENT-OFF* */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Returns the nearest (smaller than or equal to) power of two of a number*/
|
|
Packit Service |
c5cf8c |
static inline int MPL_pof2(int number)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int pof2 = 1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
while (pof2 <= number)
|
|
Packit Service |
c5cf8c |
pof2 <<= 1;
|
|
Packit Service |
c5cf8c |
pof2 >>= 1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return pof2;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Returns non-zero if val is a power of two. If ceil_pof2 is non-NULL, it sets
|
|
Packit Service |
c5cf8c |
*ceil_pof2 to the power of two that is just larger than or equal to val.
|
|
Packit Service |
c5cf8c |
That is, it rounds up to the nearest power of two. */
|
|
Packit Service |
c5cf8c |
static inline int MPL_is_pof2(int val, int *ceil_pof2)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int pof2 = 1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
while (pof2 < val)
|
|
Packit Service |
c5cf8c |
pof2 *= 2;
|
|
Packit Service |
c5cf8c |
if (ceil_pof2)
|
|
Packit Service |
c5cf8c |
*ceil_pof2 = pof2;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (pof2 == val)
|
|
Packit Service |
c5cf8c |
return 1;
|
|
Packit Service |
c5cf8c |
else
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Routine to calculate log_k of an integer */
|
|
Packit Service |
c5cf8c |
static inline int MPL_ilog(int k, int number)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int i = 1, p = k - 1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (; p - 1 < number; i++)
|
|
Packit Service |
c5cf8c |
p *= k;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return i;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Routing to calculate base^exp for integers */
|
|
Packit Service |
c5cf8c |
static inline int MPL_ipow(int base, int exp)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int result = 1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
while (exp) {
|
|
Packit Service |
c5cf8c |
if (exp & 1)
|
|
Packit Service |
c5cf8c |
result *= base;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
exp >>= 1;
|
|
Packit Service |
c5cf8c |
base *= base;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return result;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* get the number at 'digit'th location in base k representation of 'number' */
|
|
Packit Service |
c5cf8c |
static inline int MPL_getdigit(int k, int number, int digit)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
return (number / MPL_ipow(k, digit)) % k;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* set the number at 'digit'the location in base k representation of 'number' to newdigit */
|
|
Packit Service |
c5cf8c |
static inline int MPL_setdigit(int k, int number, int digit, int newdigit)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int res = number;
|
|
Packit Service |
c5cf8c |
int lshift = MPL_ipow(k, digit);
|
|
Packit Service |
c5cf8c |
res -= MPL_getdigit(k, number, digit) * lshift;
|
|
Packit Service |
c5cf8c |
res += newdigit * lshift;
|
|
Packit Service |
c5cf8c |
return res;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Implements the "mirror permutation" of "bits" low-order bits of an integer "x".
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* positions 76543210, bits==3 yields 76543012.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
ATTRIBUTE((const)) /* tells the compiler that this func only depends on its args
|
|
Packit Service |
c5cf8c |
and may be optimized much more aggressively, similar to "pure" */
|
|
Packit Service |
c5cf8c |
static inline int MPL_mirror_permutation(unsigned int x, int bits)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
/* a mask for the high order bits that should be copied as-is */
|
|
Packit Service |
c5cf8c |
int high_mask = ~((0x1 << bits) - 1);
|
|
Packit Service |
c5cf8c |
int retval = x & high_mask;
|
|
Packit Service |
c5cf8c |
int i;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < bits; ++i) {
|
|
Packit Service |
c5cf8c |
unsigned int bitval = (x & (0x1 << i)) >> i; /* 0x1 or 0x0 */
|
|
Packit Service |
c5cf8c |
retval |= bitval << ((bits - i) - 1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return retval;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* *INDENT-ON* */
|
|
Packit Service |
c5cf8c |
#if defined(__cplusplus)
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
/* *INDENT-OFF* */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#endif /* MPL_MATH_H_INCLUDED */
|