2 * Authors: Matthias Heil
8 * This code uses the C-type long double 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.
27 static long double value;
29 #define CAST_IN(val) (*((long double *)((val))))
30 #define CAST_OUT(val) ((void *)&(val))
32 #define CLEAR_BUFFER() memset((char*)&value, 0, sizeof(long double))
38 * functions defined in fltcalc.h
40 const void *fc_get_buffer(void)
42 return CAST_OUT(value);
45 const int fc_get_buffer_length(void)
47 return sizeof(long double);
50 void fc_val_from_str(const char *str, unsigned int len)
53 value = strtold(str, NULL);
56 void fc_val_from_float(long double l)
62 long double fc_val_to_float(const void *val)
67 void fc_get_min(unsigned int num_bits)
85 void fc_get_max(unsigned int num_bits)
103 void fc_get_nan(void)
105 /* nan: all exponent bit set, non-zero mantissa. not signalling wheni
106 * msb of mantissa is set (easily found using this struct */
107 union ieee854_long_double ld;
110 ld.ieee_nan.negative = 0;
111 ld.ieee_nan.exponent = 0x7FFF;
112 ld.ieee_nan.quiet_nan = 1;
113 ld.ieee_nan.mantissa0 = 42;
118 void fc_get_inf(void)
120 /* +-inf: all exponent bit set, sign is easy, one is strange XXX */
121 union ieee854_long_double ld;
124 ld.ieee_nan.negative = 0;
125 ld.ieee_nan.exponent = 0x7FFF;
126 ld.ieee_nan.quiet_nan = 0;
128 ld.ieee_nan.mantissa0 = 0;
129 ld.ieee_nan.mantissa1 = 0;
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);
156 int fc_comp(const void *a, const void *b)
158 if (CAST_IN(a) == CAST_IN(b)) return 0;
159 else return (CAST_IN(a) > CAST_IN(b))?(1):(-1);
162 char *fc_print_dec(const void *a, char *buf, int buflen)
164 snprintf(buf, buflen, "%1.30Lg", CAST_IN(a));
168 unsigned char fc_sub_bits(const void *value, unsigned num_bits, unsigned byte_ofs)
170 long double val = CAST_IN(value);
180 p = (unsigned char *)&f;
186 p = (unsigned char *)&d;
191 p = (unsigned char *)&val;