Quick actions

cmd+k|ctrl+k

Navigation

Languages

Average counter

Snippet info

Language

Cpp

Visibility

public

Author

evine

Created

2017-09-01T11:18:03Z

Updated

2017-09-01T11:25:06Z

#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;
}
INFO