#include "xmalloc.h"
-/** The number of extra precesion rounding bits */
+/** The number of extra precision rounding bits */
#define ROUNDING_BITS 2
typedef uint32_t UINT32;
power_val = alloca(calc_buffer_size);
mant_str = alloca((len)?(len):(strlen(str)));
- result->desc.exponent_size = exp_size;
- result->desc.mantissa_size = mant_size;
- result->desc.clss = NORMAL;
+ result->desc.exponent_size = desc->exponent_size;
+ result->desc.mantissa_size = desc->mantissa_size;
+ result->desc.explicit_one = desc->explicit_one;
+ result->desc.clss = NORMAL;
old_str = str;
pos = 0;
tmp_desc.clss = NORMAL;
fc_val_from_ieee754(val, &tmp_desc, tmp);
#endif /* HAVE_LONG_DOUBLE */
- return fc_cast(tmp, &tmp_desc, result);
+ return fc_cast(tmp, desc, result);
#endif
}
bias_res = ((1 << (desc->exponent_size - 1)) - 1);
#ifdef HAVE_LONG_DOUBLE
- mant_val = 64;
+ mant_val = 63;
bias_val = 0x3fff;
sign = (srcval.val.high & 0x00008000) != 0;
exponent = (srcval.val.high & 0x00007FFF) ;
value_t buildval;
ieee_descriptor_t desc;
+ unsigned mantissa_size;
#ifdef HAVE_LONG_DOUBLE
desc.exponent_size = 15;
desc.explicit_one = 0;
desc.clss = NORMAL;
#endif
+ mantissa_size = desc.mantissa_size + desc.explicit_one;
temp = alloca(calc_buffer_size);
value = fc_cast(val, &desc, temp);
mantissa1 = 0;
for (byte_offset = 0; byte_offset < 4; byte_offset++)
- mantissa1 |= sc_sub_bits(_mant(value), desc.mantissa_size, byte_offset) << (byte_offset<<3);
+ mantissa1 |= sc_sub_bits(_mant(value), mantissa_size, byte_offset) << (byte_offset << 3);
for (; (byte_offset<<3) < desc.mantissa_size; byte_offset++)
- mantissa0 |= sc_sub_bits(_mant(value), desc.mantissa_size, byte_offset) << ((byte_offset-4)<<3);
+ mantissa0 |= sc_sub_bits(_mant(value), mantissa_size, byte_offset) << ((byte_offset - 4) << 3);
#ifdef HAVE_LONG_DOUBLE
buildval.val.high = sign << 15;
char *fc_print(const fp_value *val, char *buf, int buflen, unsigned base) {
char *mul_1;
+ LLDBL flt_val;
mul_1 = alloca(calc_buffer_size);
snprintf(buf, buflen, "0.0");
break;
default:
- /* XXX to be implemented */
+ flt_val = fc_val_to_ieee754(val);
#ifdef HAVE_LONG_DOUBLE
/* XXX 30 is arbitrary */
- snprintf(buf, buflen, "%.30LE", fc_val_to_ieee754(val));
+ snprintf(buf, buflen, "%.30LE", flt_val);
#else
- snprintf(buf, buflen, "%.18E", fc_val_to_ieee754(val));
+ snprintf(buf, buflen, "%.18E", flt_val);
#endif
}
break;
snprintf(buf, buflen, "0.0");
break;
default:
+ flt_val = fc_val_to_ieee754(val);
#ifdef HAVE_LONG_DOUBLE
- snprintf(buf, buflen, "%LA", fc_val_to_ieee754(val));
+ snprintf(buf, buflen, "%LA", flt_val);
#else
- snprintf(buf, buflen, "%A", fc_val_to_ieee754(val));
+ snprintf(buf, buflen, "%A", flt_val);
#endif
}
break;
}
/* Return non-zero if a given value can be converted lossless into another precision */
-int fc_can_lossless_conv_to(const fp_value *value, char exp_size, char mant_size) {
+int fc_can_lossless_conv_to(const fp_value *value, const ieee_descriptor_t *desc) {
int v;
int exp_bias;
}
/* check if the exponent can be encoded: note, 0 and all ones are reserved for the exponent */
- exp_bias = (1 << (exp_size - 1)) - 1;
+ exp_bias = (1 << (desc->exponent_size - 1)) - 1;
v = fc_get_exponent(value) + exp_bias;
- if (0 < v && v < (1 << exp_size) - 1) {
- /* check the mantissa */
+ if (0 < v && v < (1 << desc->exponent_size) - 1) {
+ /* exponent can be encoded, now check the mantissa */
v = value->desc.mantissa_size + ROUNDING_BITS - sc_get_lowest_set_bit(_mant(value));
- return v < mant_size;
+ return v < desc->mantissa_size;
}
return 0;
}
/* does nothing if already init */
if (precision == 0) precision = FC_DEFAULT_PRECISION;
- init_strcalc(precision + 4);
+ init_strcalc(precision + 2 + ROUNDING_BITS);
- /* needs additionally two bits to round, a bit as explicit 1., and one for
+ /* needs additionally rounding bits, one bit as explicit 1., and one for
* addition overflow */
- max_precision = sc_get_precision() - 4;
+ max_precision = sc_get_precision() - (2 + ROUNDING_BITS);
if (max_precision < precision)
printf("WARNING: not enough precision available, using %d\n", max_precision);