Files
bongo/import/clucene/m4/dps_float_byte.m4
T
alexhudson ba63bbc4ee Three patches for the build system:
* make it work with automake 1.8
* simpler system for expanding path variables
* make it work with older gm4
Thanks to Albert Lee <trisk@acm.jhu.edu> for these!
2007-06-26 10:36:57 +00:00

101 lines
2.6 KiB
Plaintext

dnl dps_float_byte
AC_DEFUN([dps_float_byte],
[AC_MSG_CHECKING(whether ${CXX} supports our byte<->float conversions)
AC_CACHE_VAL(mdl_cv_have_float_byte_support,
[ AC_TRY_RUN(
changequote(<:<, >:>)dnl
<:<
typedef long double float_t;
typedef long int32_t;
typedef char uint8_t;
//float to bits conversion utilities...
union clvalue {
int32_t i;
float f; //must use a float type, else types dont match up
};
int32_t floatToIntBits(float_t value)
{
clvalue u;
int32_t e, f;
u.f = value;
e = u.i & 0x7f800000;
f = u.i & 0x007fffff;
if (e == 0x7f800000 && f != 0)
u.i = 0x7fc00000;
return u.i;
}
float_t intBitsToFloat(int32_t bits)
{
clvalue u;
u.i = bits;
return u.f;
}
float_t byteToFloat(uint8_t b) {
if (b == 0) // zero is a special case
return 0.0f;
int32_t mantissa = b & 7;
int32_t exponent = (b >> 3) & 31;
int32_t bits = ((exponent+(63-15)) << 24) | (mantissa << 21);
return intBitsToFloat(bits);
}
uint8_t floatToByte(float_t f) {
if (f < 0.0f) // round negatives up to zero
f = 0.0f;
if (f == 0.0f) // zero is a special case
return 0;
int32_t bits = floatToIntBits(f); // parse float_t into parts
int32_t mantissa = (bits & 0xffffff) >> 21;
int32_t exponent = (((bits >> 24) & 0x7f) - 63) + 15;
if (exponent > 31) { // overflow: use max value
exponent = 31;
mantissa = 7;
}
if (exponent < 0) { // underflow: use min value
exponent = 0;
mantissa = 1;
}
return (uint8_t)((exponent << 3) | mantissa); // pack into a uint8_t
}
int main(void)
{
//well know conversion
if ( floatToByte(0.5f) != 120 )
return 1;
//converting back works?
if ( floatToByte(byteToFloat(57)) != 57 )
return 1;
return 0;
}
>:>
changequote([, ]), dps_float_byte_fail=0, dps_float_byte_fail=1,
dps_float_byte_fail=2
)]
)
if test $dps_float_byte_fail -eq 0; then
AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_FUNCTIONING_FLOAT_BYTE], [], [Does not support new float byte<->float conversions])
elif test $dps_float_byte_fail -eq 1; then
AC_MSG_RESULT([no])
AC_DEFINE([HAVE_NO_FLOAT_BYTE], [], [Does not support new float byte<->float conversions])
else
AC_MSG_RESULT([unknown, assuming broken])
AC_DEFINE([HAVE_NO_FLOAT_BYTE], [], [Does not support new float byte<->float conversions])
fi
])