benfordgenerator

C Library and cli application to generate number sequences with first digits distributed according to Benford's Law
git clone git://git.defalsify.org/libbenford.git
Log | Files | Refs

benford.c (1603B)


      1 #include <math.h>
      2 #include <stdlib.h>
      3 #include <stdio.h>
      4 
      5 #include "benford.h"
      6 
      7 float benford_distribution[9] = {
      8 	0.301, // 1
      9 	0.176, // 2
     10 	0.125, // 3
     11 	0.097, // 4
     12 	0.079, // 5
     13 	0.067, // 6
     14 	0.058, // 7 
     15 	0.051, // 8
     16 	0.046  // 9
     17 };
     18 
     19 void benford_setLead_(long int* subject, int lead) {
     20 	char order;
     21 	float norm;
     22 	
     23 	order = (int)log10(*subject);
     24 	norm = (int)(*subject / (float)pow(10, order));
     25 	*subject -= norm * pow(10, order);
     26 	*subject += lead * pow(10, order);
     27 }
     28 
     29 int benford_set(benford_t* bf, long int* number) {
     30 	int lead;
     31 	
     32 	lead = benford_nextLead_(bf);
     33 	benford_setLead_(number, lead + 1);
     34 	
     35 	return 0;
     36 }
     37 
     38 int benford_setf(benford_t* bf, float* number) {
     39 	float intpart, decpart;
     40 	long int intnumber;
     41 	
     42 	decpart = modff(*number, &intpart);
     43 	intnumber = (int)intpart;
     44 	
     45 	benford_set(bf, &intnumber);
     46 	
     47 	*number = (float)intnumber + decpart;
     48 	
     49 	return 0;
     50 }
     51 
     52 int benford_nextLead_(benford_t* bf) {
     53 	int i;
     54 	float ratio;
     55 	
     56 	for (i = 0; i < 9; i++) {
     57 		
     58 		ratio = bf->counts[i] / (bf->total + 1.f);
     59 		if (ratio < benford_distribution[i]) {
     60 			bf->counts[i]++;
     61 			bf->total++;
     62 			return i;
     63 		}
     64 	}
     65 	
     66 	return -1;
     67 }
     68 
     69 /**
     70  * \fn benford_t* benford_new()
     71  * \brief Constructs a new benford number distribution generator
     72  */
     73 benford_t* benford_new() {
     74 	benford_t* bf;
     75 	int i;
     76 	
     77 	bf = malloc(sizeof(benford_t));
     78 	
     79 	if (bf == NULL) {
     80 		return 0;
     81 	}
     82 	for (i = 0; i < 9; i++) {
     83 		bf->counts[i] = 0;
     84 	}
     85 	
     86 	bf->total = 0;
     87 	
     88 	return bf;
     89 }
     90 
     91 /**
     92  * \fn benford_t* benford_free()
     93  * \brief Free up resources from distribution generator
     94  */
     95 void benford_free(benford_t* bf) {
     96 	if (bf != NULL) {
     97 		free(bf);
     98 	}
     99 }