summaryrefslogtreecommitdiff
path: root/ext/fputils/fp80.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/fputils/fp80.c')
-rw-r--r--ext/fputils/fp80.c56
1 files changed, 22 insertions, 34 deletions
diff --git a/ext/fputils/fp80.c b/ext/fputils/fp80.c
index 8100a4d99..aaa4ee5a0 100644
--- a/ext/fputils/fp80.c
+++ b/ext/fputils/fp80.c
@@ -28,6 +28,7 @@
*/
#include <fputils/fp80.h>
+#include <fputils/fp64.h>
#include "fpbits.h"
#include <assert.h>
@@ -35,39 +36,13 @@
#include <stdio.h>
-typedef union {
- uint64_t bits;
- double value;
-} fp64_t;
-
-const fp80_t fp80_pinf = BUILD_FP80(0, 0, FP80_EXP_SPECIAL);
-const fp80_t fp80_ninf = BUILD_FP80(1, 0, FP80_EXP_SPECIAL);
-const fp80_t fp80_qnan = BUILD_FP80(0, FP80_FRAC_QNAN, FP80_EXP_SPECIAL);
+const fp80_t fp80_pinf = BUILD_FP80(0, 0, FP80_EXP_SPECIAL);
+const fp80_t fp80_ninf = BUILD_FP80(1, 0, FP80_EXP_SPECIAL);
+const fp80_t fp80_qnan = BUILD_FP80(0, FP80_FRAC_QNAN, FP80_EXP_SPECIAL);
const fp80_t fp80_qnani = BUILD_FP80(1, FP80_FRAC_QNANI, FP80_EXP_SPECIAL);
-const fp80_t fp80_snan = BUILD_FP80(0, FP80_FRAC_SNAN, FP80_EXP_SPECIAL);
-const fp80_t fp80_nan = BUILD_FP80(0, FP80_FRAC_QNAN, FP80_EXP_SPECIAL);
-
-static const fp64_t fp64_pinf = BUILD_FP64(0, 0, FP64_EXP_SPECIAL);
-static const fp64_t fp64_ninf = BUILD_FP64(1, 0, FP64_EXP_SPECIAL);
-static const fp64_t fp64_qnan = BUILD_FP64(0, FP64_FRAC_QNAN,
- FP64_EXP_SPECIAL);
-static const fp64_t fp64_nqnan = BUILD_FP64(1, FP64_FRAC_QNAN,
- FP64_EXP_SPECIAL);
-static const fp64_t fp64_qnani = BUILD_FP64(1, FP64_FRAC_QNANI,
- FP64_EXP_SPECIAL);
-static const fp64_t fp64_snan = BUILD_FP64(0, FP64_FRAC_SNAN,
- FP64_EXP_SPECIAL);
-static const fp64_t fp64_nsnan = BUILD_FP64(1, FP64_FRAC_SNAN,
- FP64_EXP_SPECIAL);
-
-static double
-build_fp64(int sign, uint64_t frac, int exp)
-{
- const fp64_t f = BUILD_FP64(sign, frac, exp);
-
- return f.value;
-}
+const fp80_t fp80_snan = BUILD_FP80(0, FP80_FRAC_SNAN, FP80_EXP_SPECIAL);
+const fp80_t fp80_nan = BUILD_FP80(0, FP80_FRAC_QNAN, FP80_EXP_SPECIAL);
int
fp80_sgn(fp80_t fp80)
@@ -167,6 +142,12 @@ fp80_classify(fp80_t fp80)
double
fp80_cvtd(fp80_t fp80)
{
+ return fp80_cvtfp64(fp80).value;
+}
+
+fp64_t
+fp80_cvtfp64(fp80_t fp80)
+{
const int sign = fp80.repr.se & FP80_SIGN_BIT;
if (!fp80_isspecial(fp80)) {
@@ -191,12 +172,12 @@ fp80_cvtd(fp80_t fp80)
if (fp80_isinf(fp80)) {
return build_fp64(sign, 0, FP64_EXP_SPECIAL);
} else if (fp80_issnan(fp80)) {
- return fp80_sgn(fp80) > 0 ? fp64_snan.value : fp64_nsnan.value;
+ return fp80_sgn(fp80) > 0 ? fp64_snan : fp64_nsnan;
} else if (fp80_isqnani(fp80)) {
- return fp64_qnani.value;
+ return fp64_qnani;
} else {
assert(fp80_isqnan(fp80));
- return fp80_sgn(fp80) > 0 ? fp64_qnan.value : fp64_nqnan.value;
+ return fp80_sgn(fp80) > 0 ? fp64_qnan : fp64_nqnan;
}
}
}
@@ -205,6 +186,13 @@ fp80_t
fp80_cvfd(double value)
{
const fp64_t fp64 = { .value = value };
+
+ return fp80_cvffp64(fp64);
+}
+
+fp80_t
+fp80_cvffp64(fp64_t fp64)
+{
const uint64_t frac = FP64_FRAC(fp64);
const unsigned exp = FP64_EXP(fp64);
const int unb_exp = exp - FP64_EXP_BIAS;