summaryrefslogtreecommitdiff
path: root/ext/fputils
diff options
context:
space:
mode:
Diffstat (limited to 'ext/fputils')
-rw-r--r--ext/fputils/configure.in6
-rw-r--r--ext/fputils/fp80.c20
-rw-r--r--ext/fputils/fpbits.h8
-rw-r--r--ext/fputils/include/fputils/fp80.h14
-rw-r--r--ext/fputils/tests/fp80_cvtd.c13
5 files changed, 35 insertions, 26 deletions
diff --git a/ext/fputils/configure.in b/ext/fputils/configure.in
index 59a21c18e..bb2291b6f 100644
--- a/ext/fputils/configure.in
+++ b/ext/fputils/configure.in
@@ -12,10 +12,14 @@ DX_INIT_DOXYGEN([libfputils])
AC_REQUIRE_AUX_FILE([tap-driver.sh])
AC_PROG_CC
-AM_PROG_CC_C_O
+AC_PROG_CC_C99
AC_PROG_LIBTOOL
AC_PROG_AWK
+if test "x$ac_cv_prog_cc_c99" = "xno"; then
+ AC_MSG_ERROR([Could not enable C99 support in compiler.])
+fi
+
AM_CFLAGS="-Wall -Werror"
AM_CPPFLAGS="-I\$(abs_top_srcdir)/include"
diff --git a/ext/fputils/fp80.c b/ext/fputils/fp80.c
index 703b07ac9..8100a4d99 100644
--- a/ext/fputils/fp80.c
+++ b/ext/fputils/fp80.c
@@ -36,10 +36,8 @@
#include <stdio.h>
typedef union {
- union {
- uint64_t bits;
- double value;
- };
+ uint64_t bits;
+ double value;
} fp64_t;
@@ -74,7 +72,7 @@ build_fp64(int sign, uint64_t frac, int exp)
int
fp80_sgn(fp80_t fp80)
{
- return (fp80.u.repr.se & FP80_SIGN_BIT) ? -1 : 1;
+ return (fp80.repr.se & FP80_SIGN_BIT) ? -1 : 1;
}
int
@@ -105,9 +103,9 @@ fp80_isqnan(fp80_t fp80)
int
fp80_isqnani(fp80_t fp80)
{
- const uint64_t frac_low = fp80.u.repr.fi & (FP80_FRAC_MASK >> 1);
+ const uint64_t frac_low = fp80.repr.fi & (FP80_FRAC_MASK >> 1);
- return fp80_isqnan(fp80) && (fp80.u.repr.se & FP80_SIGN_BIT) && !frac_low;
+ return fp80_isqnan(fp80) && (fp80.repr.se & FP80_SIGN_BIT) && !frac_low;
}
int
@@ -133,7 +131,7 @@ fp80_isnan(fp80_t fp80)
int
fp80_iszero(fp80_t fp80)
{
- return fp80.u.repr.fi == 0 && FP80_EXP(fp80) == 0 ? fp80_sgn(fp80) : 0;
+ return fp80.repr.fi == 0 && FP80_EXP(fp80) == 0 ? fp80_sgn(fp80) : 0;
}
int
@@ -169,10 +167,10 @@ fp80_classify(fp80_t fp80)
double
fp80_cvtd(fp80_t fp80)
{
- const int sign = fp80.u.repr.se & FP80_SIGN_BIT;
+ const int sign = fp80.repr.se & FP80_SIGN_BIT;
if (!fp80_isspecial(fp80)) {
- const uint64_t frac = fp80.u.repr.fi;
+ const uint64_t frac = fp80.repr.fi;
const int unb_exp = FP80_EXP(fp80) - FP80_EXP_BIAS;
const int fp64_exp = unb_exp + FP64_EXP_BIAS;
const uint64_t fp64_frac = frac >> (FP80_FRAC_BITS - FP64_FRAC_BITS);
@@ -242,6 +240,6 @@ void
fp80_debug_dump(FILE *fout, fp80_t fp80)
{
fprintf(fout, "sgn: %i, int: %i, frac: 0x%llx, exp: 0x%x (%i)\n",
- fp80_sgn(fp80), !!(fp80.u.repr.fi & FP80_INT_BIT), FP80_FRAC(fp80),
+ fp80_sgn(fp80), !!(fp80.repr.fi & FP80_INT_BIT), FP80_FRAC(fp80),
FP80_EXP(fp80), FP80_EXP(fp80) - FP80_EXP_BIAS);
}
diff --git a/ext/fputils/fpbits.h b/ext/fputils/fpbits.h
index 9fb934843..335a122d3 100644
--- a/ext/fputils/fpbits.h
+++ b/ext/fputils/fpbits.h
@@ -76,15 +76,15 @@
#define BUILD_FP80(sign, frac, exp) \
{ \
- .u.repr.se = BUILD_FP80_SE(sign, exp), \
- .u.repr.fi = BUILD_FP80_FI(frac, exp) \
+ .repr.se = BUILD_FP80_SE(sign, exp), \
+ .repr.fi = BUILD_FP80_FI(frac, exp) \
}
#define FP80_FRAC(fp80) \
- (fp80.u.repr.fi & FP80_FRAC_MASK)
+ (fp80.repr.fi & FP80_FRAC_MASK)
#define FP80_EXP(fp80) \
- (fp80.u.repr.se & FP80_EXP_MASK)
+ (fp80.repr.se & FP80_EXP_MASK)
#define FP64_FRAC(fp64) \
(fp64.bits & FP64_FRAC_MASK)
diff --git a/ext/fputils/include/fputils/fp80.h b/ext/fputils/include/fputils/fp80.h
index e584baab4..70acb6cb1 100644
--- a/ext/fputils/include/fputils/fp80.h
+++ b/ext/fputils/include/fputils/fp80.h
@@ -46,14 +46,12 @@ extern "C" {
*/
/** Internal representation of an 80-bit float. */
-typedef struct {
- union {
- char bits[10];
- struct {
- uint64_t fi;
- uint16_t se;
- } repr;
- } u;
+typedef union {
+ char bits[10];
+ struct {
+ uint64_t fi;
+ uint16_t se;
+ } repr;
} fp80_t;
/** Constant representing +inf */
diff --git a/ext/fputils/tests/fp80_cvtd.c b/ext/fputils/tests/fp80_cvtd.c
index 425a5c44a..5a49d3426 100644
--- a/ext/fputils/tests/fp80_cvtd.c
+++ b/ext/fputils/tests/fp80_cvtd.c
@@ -35,6 +35,15 @@
#include <stdio.h>
#include <stdlib.h>
+/* We provide our own version of isinf_sgn since the C99 standard
+ * doesn't guarantee that isinf() returns the sign of the infinity
+ * (most implementations do). */
+static inline int
+isinf_sgn(double x)
+{
+ return isinf(x) ? (signbit(x) ? -1 : 1) : 0;
+}
+
static void
test_fp80_cvtd_class(const char *name, fp80_t fin, int class)
{
@@ -48,10 +57,10 @@ test_fp80_cvtd_class(const char *name, fp80_t fin, int class)
}
static void
-test_fp80_cvtd_inf(const char *name, fp80_t fin, int inf_class)
+test_fp80_cvtd_inf(const char *name, fp80_t fin, int expected_inf_class)
{
double d = fp80_cvtd(fin);
- if (isinf(d) != inf_class) {
+ if (isinf_sgn(d) != expected_inf_class) {
test_diag("wrong infinity type");
test_fail(name);
} else {