ref: 9bfee88015312110df5100c28e5db198e79dbd2b
parent: bac0583ae0eef43a040806983b74cd36c17cf6f4
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Mon Nov 30 07:25:37 EST 2020
fix more floating point issues
--- a/flmain.c
+++ b/flmain.c
@@ -30,7 +30,7 @@
char fname_buf[1024];
#ifdef __plan9__
- setfcr(FPPDBL|FPRNR|FPINVAL|FPOVFL);
+ setfcr(FPPDBL|FPRNR|FPOVFL);
#endif
fl_init(512*1024);
--- a/llt/lltinit.c
+++ b/llt/lltinit.c
@@ -29,16 +29,21 @@
ios_init_stdstreams();
+#ifdef __plan9__
+ D_PNAN = NaN();
+ D_NNAN = NaN(); *(u64int*)&D_NNAN |= 1<<31;
+ D_PINF = Inf(1);
+ D_NINF = Inf(-1);
+ u32int x;
+ x = 0x7fc00000; memcpy(&F_PNAN, &x, 4);
+ x = 0xffc00000; memcpy(&F_NNAN, &x, 4);
+ x = 0x7f800000; memcpy(&F_PINF, &x, 4);
+ x = 0xff800000; memcpy(&F_NINF, &x, 4);
+#else
D_PNAN = strtod("+NaN",NULL);
D_NNAN = -strtod("+NaN",NULL);
D_PINF = strtod("+Inf",NULL);
D_NINF = strtod("-Inf",NULL);
-#ifdef __plan9__
- F_PNAN = D_PNAN;
- F_NNAN = D_NNAN;
- F_PINF = D_PINF;
- F_NINF = D_NINF;
-#else
F_PNAN = strtof("+NaN",NULL);
F_NNAN = -strtof("+NaN",NULL);
F_PINF = strtof("+Inf",NULL);
--- a/operators.c
+++ b/operators.c
@@ -3,15 +3,17 @@
#include "ieee754.h"
#ifdef __plan9__
-#define trunc(x) floor(x)
+STATIC_INLINE double fpart(double arg)
+{
+ return modf(arg, NULL);
+}
#else
extern double trunc(double x);
-#endif
-
STATIC_INLINE double fpart(double arg)
{
return arg - trunc(arg);
}
+#endif
// given a number, determine an appropriate type for storing it
#if 0
@@ -170,7 +172,11 @@
case T_INT64: return *(int64_t*)a < *(int64_t*)b;
case T_UINT64: return *(uint64_t*)a < *(uint64_t*)b;
case T_FLOAT: return *(float*)a < *(float*)b;
- case T_DOUBLE: return *(double*)a < *(double*)b;
+ case T_DOUBLE: return *(double*)a < *(double*)b
+#ifdef __plan9__
+ && !isNaN(*(double*)a) && !isNaN(*(double*)b)
+#endif
+ ;
}
return 0;
}
@@ -187,7 +193,11 @@
case T_INT64: return *(int64_t*)a == *(int64_t*)b;
case T_UINT64: return *(uint64_t*)a == *(uint64_t*)b;
case T_FLOAT: return *(float*)a == *(float*)b;
- case T_DOUBLE: return *(double*)a == *(double*)b;
+ case T_DOUBLE: return *(double*)a == *(double*)b
+#ifdef __plan9__
+ && !isNaN(*(double*)a)
+#endif
+ ;
}
return 0;
}
@@ -200,9 +210,14 @@
double da = conv_to_double(a, atag);
double db = conv_to_double(b, btag);
+#ifdef __plan9__
+ if (isNaN(da) || isNaN(db))
+ return 0;
+#endif
+
// casting to double will only get the wrong answer for big int64s
// that differ in low bits
- if (da < db)
+ if (da < db && !isNaN(da) && !isNaN(db))
return 1;
if (db < da)
return 0;