113 lines
2.8 KiB
C
113 lines
2.8 KiB
C
//LogFloat.c
|
|
//Logs max, min and precision of a floating point value
|
|
#include <stdio.h>
|
|
#include "LogFloat.h"
|
|
|
|
struct LogFloatEntry {
|
|
char id[128];
|
|
float min, max, precision;
|
|
int counter;
|
|
};
|
|
|
|
#define MAX_LF_ENTRIES 1000
|
|
struct LogFloatEntry lf_entries[MAX_LF_ENTRIES];
|
|
int lf_total=0;
|
|
|
|
_inline struct LogFloatEntry *_lfAdd(char *id) {
|
|
//Adds a new entry.
|
|
//NULL == Array full.
|
|
|
|
if (lf_total==MAX_LF_ENTRIES) return NULL;
|
|
|
|
strcpy(lf_entries[lf_total].id, id);
|
|
lf_entries[lf_total].max=lf_entries[lf_total].min=0.0f;
|
|
lf_entries[lf_total].precision=1.0f;
|
|
lf_entries[lf_total].counter=0;
|
|
|
|
return &lf_entries[lf_total++];
|
|
}
|
|
|
|
_inline struct LogFloatEntry *_lfFind(char *id) {
|
|
//Finds an existing entry.
|
|
//NULL == No matching id
|
|
|
|
struct LogFloatEntry *cur=&lf_entries[0], *last=&lf_entries[lf_total];
|
|
while (cur<=last) {
|
|
//Change this is case insensitive matching is desired.
|
|
if (!strcmp(id, cur->id)) return cur;
|
|
cur++;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
_inline struct LogFloatEntry *_lfGet(char *id) {
|
|
//Gets an entry. Returns an entry if it already exists, otherwise a new entry is created.
|
|
struct LogFloatEntry *cur=_lfFind(id);
|
|
|
|
if (!cur) cur=_lfAdd(id);
|
|
return cur;
|
|
}
|
|
|
|
int LogFloatInit() {
|
|
|
|
lf_total=0;
|
|
return 1;
|
|
}
|
|
|
|
void LogFloatClose() {
|
|
lf_total=0;
|
|
}
|
|
|
|
void LogFloatResults(char *fn) {
|
|
int i;
|
|
FILE *f=fopen(fn, "w+");
|
|
|
|
if (f) {
|
|
fprintf(f, "ID\tMin\tMax\tPrecision\tCount\n\n");
|
|
for (i=0; i<lf_total; i++)
|
|
fprintf(f, "%s:\t%f\t%f\t%e\t%d\n", lf_entries[i].id, lf_entries[i].min, lf_entries[i].max, lf_entries[i].precision, lf_entries[i].counter);
|
|
fprintf(f, "\nTotal items logged: %d", lf_total);
|
|
|
|
fclose(f);
|
|
}
|
|
}
|
|
|
|
float LogFloat(float f, char *id, int index, int precision) {
|
|
//Params:
|
|
// f: Float value to be logged
|
|
// id: string ID (name) of the float variable
|
|
// index: index of f in the event that f is a member of an array. Specify index < 0 for no index.
|
|
//precision: Indicates max precision truncation to be applied to the return float. If no precision
|
|
// truncating is desired, set precision < 0.
|
|
|
|
//Return value:
|
|
//if precision >=0 && <= 32, return value is f truncated to the fixed point precision "precision".
|
|
//otherwise return value == f.
|
|
|
|
struct LogFloatEntry *cur;
|
|
float tmp;
|
|
|
|
if (index>=0) {
|
|
char newId[256];
|
|
sprintf(newId, "%s[%d]", id, index);
|
|
cur=_lfGet(newId);
|
|
} else cur=_lfGet(id);
|
|
|
|
if (cur) {
|
|
cur->counter++;
|
|
if (cur->max<f) cur->max=f;
|
|
if (cur->min>f) cur->min=f;
|
|
tmp=(float)fabs(f);
|
|
if (tmp<1.0f&&f!=0.0f)
|
|
if (tmp<cur->precision) cur->precision=tmp;
|
|
} //else Error: we ran out of entry storage
|
|
|
|
if (precision>=0) {
|
|
float f2=(float)(2^precision);
|
|
tmp=f*f2;
|
|
return tmp/f2;
|
|
}
|
|
|
|
return f;
|
|
} |