#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
struct Counter_Object{
uint8_t counter;
union{
uint64_t raw;
uint8_t e[8];
};
};
int rand1()
{
return (int)((double)rand() / (RAND_MAX / 2.0));
}
void avg_small_nums()
{
Counter_Object t = {};
for(size_t i = 0; i < 1023; ++i)
{
uint64_t add_num = rand1();
add_num *= 0x0101010101010101;
t.raw += add_num;
t.counter += 1;
if(t.counter >= 8)
{
t.counter = 0;
t.raw >>= 8;
}
}
printf("%f\n", t.e[0] / (64.0 - (8 - t.counter)));
}
size_t popcnt(uint64_t v)
{
size_t result = 0;
for(size_t i = 0; i < 64; ++i)
{
result += v & 1;
v >>= 1;
}
return result;
}
// All of this is perhaps done better with just a shift_left + bit_or + popcnt.
// Would easily extend to larger sizes in assembly.
// But it's a bit gnarly to write in C++ because I need the carry bit.
void avg_bits()
{
uint64_t t = 0;
for(size_t i = 0; i < 1023; ++i)
{
size_t add_num = rand1();
t <<= 1;
t |= add_num;
}
printf("%f\n", (double)popcnt(t) / 64.0);
}
int main()
{
srand(0);
avg_small_nums();
srand(0);
avg_bits();
return 0;
}