countbits.cpp

// $Id: countbits.cpp,v 1.1 2002/04/07 18:50:51 erngui Exp $
//
//  Splits a file into 8, 16, 24, 32 or 64 bit chunks and 
//  counts the ocurrences of each bit.
//
//  -- Ernesto Guisado (erngui@acm.org)
//  
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

void accumbits(unsigned char b, unsigned long count[CHAR_BIT])
{
  int i = 0;
  while (b) {
    if (b & 0x1)
      count[i]++;
    b >>= 1;
    i++;
  }
}

void printcounts(unsigned long* counts, int ncounts, unsigned long total)
{
  fprintf(stdout, "---\nCounting for %d bits\n", ncounts);
  for (int i=0; i<ncounts; i++) {
	fprintf(stdout,
      "Bit %d: %d = %.2f%%\n", i,
	  counts[i], 
	  (counts[i]*100.0f)/total);
  }
}

int main(int argc, char* argv[])
{
  FILE *f = fopen(argv[1], "rb");
  
  unsigned long count1[CHAR_BIT  ] = {0};
  unsigned long count2[CHAR_BIT*2] = {0};
  unsigned long count3[CHAR_BIT*3] = {0};
  unsigned long count4[CHAR_BIT*4] = {0};
  unsigned long count8[CHAR_BIT*8] = {0};

  unsigned char b;
  unsigned long total = 0;
  while (fread(&b, 1, 1, f)==1) {
    accumbits(b, &count1[0]);
	accumbits(b, &count2[(total%2)*CHAR_BIT]);
	accumbits(b, &count3[(total%3)*CHAR_BIT]);
	accumbits(b, &count4[(total%4)*CHAR_BIT]);
	accumbits(b, &count8[(total%8)*CHAR_BIT]);
    total++;
  }
  fclose(f);

  printcounts(count1, CHAR_BIT, total);
  printcounts(count2, CHAR_BIT*2, total/2);
  printcounts(count3, CHAR_BIT*3, total/3);
  printcounts(count4, CHAR_BIT*4, total/4);
  printcounts(count8, CHAR_BIT*8, total/8);
  
  return 0;
}