summaryrefslogtreecommitdiff
path: root/sys/src/ape/lib/ap/math/modf.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/ape/lib/ap/math/modf.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/ape/lib/ap/math/modf.c')
-rwxr-xr-xsys/src/ape/lib/ap/math/modf.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/sys/src/ape/lib/ap/math/modf.c b/sys/src/ape/lib/ap/math/modf.c
new file mode 100755
index 000000000..4326cf44a
--- /dev/null
+++ b/sys/src/ape/lib/ap/math/modf.c
@@ -0,0 +1,53 @@
+#include <math.h>
+#include <errno.h>
+
+/* modf suitable for IEEE double-precision */
+
+#define MASK 0x7ffL
+#define SIGN 0x80000000
+#define SHIFT 20
+#define BIAS 1022L
+
+typedef union
+{
+ double d;
+ struct
+ {
+ long ms;
+ long ls;
+ } i;
+} Cheat;
+
+double
+modf(double d, double *ip)
+{
+ Cheat x;
+ int e;
+
+ if(-1 < d && d < 1) {
+ *ip = 0;
+ return d;
+ }
+ x.d = d;
+ x.i.ms &= ~SIGN;
+ e = (x.i.ms >> SHIFT) & MASK;
+ if(e == MASK || e == 0){
+ errno = EDOM;
+ *ip = (d > 0)? HUGE_VAL : -HUGE_VAL;
+ return 0;
+ }
+ e -= BIAS;
+ if(e <= SHIFT+1) {
+ x.i.ms &= ~(0x1fffffL >> e);
+ x.i.ls = 0;
+ } else
+ if(e <= SHIFT+33)
+ x.i.ls &= ~(0x7fffffffL >> (e-SHIFT-2));
+ if(d > 0){
+ *ip = x.d;
+ return d - x.d;
+ }else{
+ *ip = -x.d;
+ return d + x.d;
+ }
+}