add qispowerof2() to qfunc.c, improve log2() code

Change zispowerof2() interaface to take a FULL ptr as the 2nd arg:
zispowerof2(ZVALUE z, FULL *log2).

Added qispowerof2(NUMBER *q, NUMBER **qlog2) to qfunc.c.

Change log2() builtin to use the new qispowerof2() internal interface.

Update LIBRARY to reflect the new zispowerof2() internal interface
and the new qispowerof2() internal interface.
This commit is contained in:
Landon Curt Noll
2023-08-27 23:50:44 -07:00
parent 4e5fcc8812
commit 4dbc4dfe9a
6 changed files with 131 additions and 89 deletions

17
zfunc.c
View File

@@ -2243,30 +2243,29 @@ zissquare(ZVALUE z)
*
* given:
* z value to check if it is a power of 2
* zlog2 >= 0 ==> *zlog2 power of 2 of z (return true)
* < 0 z is not a power of 2 (return false)
* log2 when z is an integer power of 2 (true return), *log2 is set to log base 2 of z
* when z is NOT an integer power of 2 (false return), *log2 is not touched
*
* returns:
* true z is a power of 2
* false z is not a power of 2
*/
bool
zispowerof2(ZVALUE z, ZVALUE *zlog2)
zispowerof2(ZVALUE z, FULL *log2)
{
FULL ilogz=0; /* potential log base 2 return value or -1 */
FULL ilogz; /* potential log base 2 return value or -1 */
HALF tophalf; /* most significant HALF in z */
LEN len; /* length of z in HALFs */
int i;
/* firewall */
if (zlog2 == NULL) {
math_error("%s: zlog2 NULL", __func__);
if (log2 == NULL) {
math_error("%s: log2 NULL", __func__);
not_reached();
}
/* zero and negative values are never integer powers of 2 */
if (ziszero(z) || zisneg(z)) {
*zlog2 = _neg_one_;
return false;
}
@@ -2283,7 +2282,6 @@ zispowerof2(ZVALUE z, ZVALUE *zlog2)
len = z.len;
for (i=0, ilogz=0; i < len-1; ++i, ilogz+=BASEB) {
if (z.v[i] != 0) {
*zlog2 = _neg_one_;
return false;
}
}
@@ -2297,7 +2295,6 @@ zispowerof2(ZVALUE z, ZVALUE *zlog2)
*/
tophalf = z.v[len-1];
if ((tophalf == 0) || ((tophalf & (tophalf-1)) != 0)) {
*zlog2 = _neg_one_;
return false;
}
@@ -2311,6 +2308,6 @@ zispowerof2(ZVALUE z, ZVALUE *zlog2)
/*
* return power of 2
*/
utoz(ilogz, zlog2);
*log2 = ilogz;
return true;
}