104 lines
1.8 KiB
C
104 lines
1.8 KiB
C
#include "test.h"
|
|
|
|
/* Return 1 when x contains an odd number of 1s; 0 otherwise.
|
|
Assume w=32 */
|
|
int odd_ones(unsigned x) {
|
|
x ^= x >> 16;
|
|
x ^= x >> 8;
|
|
x ^= x >> 4;
|
|
x ^= x >> 2;
|
|
x ^= x >> 1;
|
|
return x & 1;
|
|
}
|
|
|
|
/*
|
|
* Generate mask indicating leftmost 1 in x. Assume w=32.
|
|
* For example, 0xFF00 -> 0x8000, and 0x6600 --> 0x4000.
|
|
* If x = 0, then return 0.
|
|
*/
|
|
int leftmost_one(unsigned x) {
|
|
unsigned t = x;
|
|
t >>= 1;
|
|
|
|
t |= t >> 1;
|
|
t |= t >> 2;
|
|
t |= t >> 4;
|
|
t |= t >> 8;
|
|
t |= t >> 16;
|
|
|
|
return (t + 1) & x;
|
|
}
|
|
|
|
unsigned unsigned_high_prod(unsigned x, unsigned y) {
|
|
int w = sizeof(int) << 3;
|
|
return signed_high_prod(x, y) + (((int) y >> (w - 1)) & x) + (((int) x >> (w - 1)) & y);
|
|
}
|
|
|
|
int threefourths(int x) {
|
|
int p = x >> 2, q = x & 3;
|
|
return p + (p << 1) + q - (!!q & (~x >> 31));
|
|
}
|
|
|
|
/* computs 0.5*f. If f is NaN, then return f. */
|
|
float_bits float_half(float_bits uf) {
|
|
float_bits s = uf & 0x80000000, f = uf & 0x007FFFFF, e = (uf >> 23) & 0xFF;
|
|
|
|
if (e == 0xFF) {
|
|
return uf;
|
|
}
|
|
|
|
if (e > 1) {
|
|
e--;
|
|
} else {
|
|
if (e == 1) {
|
|
f |= 1 << 23;
|
|
e = 0;
|
|
}
|
|
int t = f;
|
|
f >>= 1;
|
|
if (t & f & 1) {
|
|
f++;
|
|
}
|
|
}
|
|
return s | (e << 23) | f;
|
|
}
|
|
|
|
/* Compute (float) i */
|
|
float_bits float_i2f(int i) {
|
|
if (i == -0x7FFFFFFF - 1) {
|
|
return 0xCF000000;
|
|
}
|
|
|
|
if (i == 0) {
|
|
return 0;
|
|
}
|
|
|
|
float_bits s = 0, f, e;
|
|
if (i < 0) {
|
|
i = -i;
|
|
s = 0x80000000;
|
|
}
|
|
|
|
int hb = 30;
|
|
while (!(i >> hb)) {
|
|
hb--;
|
|
}
|
|
|
|
i ^= 1 << hb;
|
|
e = hb + 127;
|
|
int dif = hb - 23;
|
|
if (dif > 0) {
|
|
f = i >> dif;
|
|
if ((i & ((1 << dif) - 1)) + (f & 1) > (1 << (dif - 1))) {
|
|
f++;
|
|
if (f & 0x00800000) {
|
|
f = 0;
|
|
e++;
|
|
}
|
|
}
|
|
} else {
|
|
f = i << -dif;
|
|
}
|
|
|
|
return s | (e << 23) | f;
|
|
} |