2 * Authors: Matthias Heil
8 * This code uses the C-type LLDBL to respesent floating
9 * point values. This is bad because:
11 * 1.) It depends on IEEE arithmetic on the compilation engine (hardly a problem)
12 * 2.) The existance on the type and its bits size (may be identical to double or even float)
13 * 3.) Arithmetic operations will be done with "higher order" precision, which might be wrong
15 * Replace this code ASAP.
23 #ifdef USE_LONG_DOUBLE
24 /* have long double type */
26 /* only defined in C99 mode */
27 extern long double strtold(const char *str, char **end);
29 #define strtoLLD strtold
32 /* don't have long double type */
34 extern double strtod(const char *str, char **end);
36 #define strtoLLD strtod
45 #define CAST_IN(val) (*((LLDBL *)((val))))
46 #define CAST_OUT(val) ((void *)&(val))
48 #define CLEAR_BUFFER() memset((char*)&value, 0, sizeof(LLDBL))
54 * functions defined in fltcalc.h
56 const void *fc_get_buffer(void)
58 return CAST_OUT(value);
61 const int fc_get_buffer_length(void)
66 void fc_val_from_str(const char *str, unsigned int len)
69 value = strtoLLD(str, NULL);
72 void fc_val_from_float(LLDBL l)
78 LLDBL fc_val_to_float(const void *val)
83 void fc_get_min(unsigned int num_bits)
88 * Beware: FLT_MIN is the "Minimum normalised float",
89 * not the smallest number in arithmetic sense
105 void fc_get_max(unsigned int num_bits)
123 void fc_get_nan(void)
125 value = strtoLLD("nan", NULL);
129 void fc_get_inf(void)
131 value = strtoLLD("inf", NULL);
134 void fc_calc(const void *a, const void *b, int opcode)
140 value = CAST_IN(a) + CAST_IN(b);
143 value = CAST_IN(a) - CAST_IN(b);
146 value = CAST_IN(a) * CAST_IN(b);
149 value = CAST_IN(a) / CAST_IN(b);
157 int fc_comp(const void *a, const void *b)
160 if (CAST_IN(a) == CAST_IN(b)) {
163 else if (CAST_IN(a) > CAST_IN(b)) {
171 char *fc_print_dec(const void *a, char *buf, int buflen)
175 #ifdef USE_LONG_DOUBLE
176 n = snprintf(buf, buflen, "%1.30Lg", CAST_IN(a));
178 n = snprintf(buf, buflen, "%1.30g", CAST_IN(a));
181 if (n > -1 && n < buflen) {
183 * for some backends we always want to present 0 as 0.0
184 * as I could not find the best format to express this, add
185 * a .0 explicitely if not found
187 if (NULL == strrchr(buf, '.'))
188 strncat(buf, ".0", buflen);
194 unsigned char fc_sub_bits(const void *value, unsigned num_bits, unsigned byte_ofs)
196 LLDBL val = CAST_IN(value);
206 p = (unsigned char *)&f;
212 p = (unsigned char *)&d;
217 p = (unsigned char *)&val;