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 }