Browse Source

Added nextafter implementation

Christophe Riccio 14 years ago
parent
commit
16a9250842
1 changed files with 138 additions and 0 deletions
  1. 138 0
      glm/gtx/ulp.inl

+ 138 - 0
glm/gtx/ulp.inl

@@ -10,6 +10,144 @@
 #include <cmath>
 #include <cfloat>
 
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+#define EXTRACT_WORDS(ix0,ix1,d)                                \
+do {                                                            \
+  ieee_double_shape_type ew_u;                                  \
+  ew_u.value = (d);                                             \
+  (ix0) = ew_u.parts.msw;                                       \
+  (ix1) = ew_u.parts.lsw;                                       \
+} while (0)
+
+#define GET_FLOAT_WORD(i,d)                                     \
+do {                                                            \
+  ieee_float_shape_type gf_u;                                   \
+  gf_u.value = (d);                                             \
+  (i) = gf_u.word;                                              \
+} while (0)
+
+#define SET_FLOAT_WORD(d,i)                                     \
+do {                                                            \
+  ieee_float_shape_type sf_u;                                   \
+  sf_u.word = (i);                                              \
+  (d) = sf_u.value;                                             \
+} while (0)
+
+#define INSERT_WORDS(d,ix0,ix1)                                 \
+do {                                                            \
+  ieee_double_shape_type iw_u;                                  \
+  iw_u.parts.msw = (ix0);                                       \
+  iw_u.parts.lsw = (ix1);                                       \
+  (d) = iw_u.value;                                             \
+} while (0)
+
+float nextafterf(float x, float y)
+{
+        volatile float t;
+        int32_t hx,hy,ix,iy;
+
+        GET_FLOAT_WORD(hx,x);
+        GET_FLOAT_WORD(hy,y);
+        ix = hx&0x7fffffff;             // |x|
+        iy = hy&0x7fffffff;             // |y|
+
+        if((ix>0x7f800000) ||   // x is nan 
+           (iy>0x7f800000))     // y is nan 
+           return x+y;
+        if(x==y) return y;              // x=y, return y
+        if(ix==0) {                             // x == 0
+            SET_FLOAT_WORD(x,(hy&0x80000000)|1);// return +-minsubnormal
+            t = x*x;
+            if(t==x) return t; else return x;   // raise underflow flag
+        }
+        if(hx>=0) {                             // x > 0 
+            if(hx>hy) {                         // x > y, x -= ulp
+                hx -= 1;
+            } else {                            // x < y, x += ulp
+                hx += 1;
+            }
+        } else {                                // x < 0
+            if(hy>=0||hx>hy){                   // x < y, x -= ulp
+                hx -= 1;
+            } else {                            // x > y, x += ulp
+                hx += 1;
+            }
+        }
+        hy = hx&0x7f800000;
+        if(hy>=0x7f800000) return x+x;  // overflow
+        if(hy<0x00800000) {             // underflow
+            t = x*x;
+            if(t!=x) {          // raise underflow flag
+                SET_FLOAT_WORD(y,hx);
+                return y;
+            }
+        }
+        SET_FLOAT_WORD(x,hx);
+        return x;
+}
+*/
+/*
+double nextafter(double x, double y)
+{
+        volatile double t;
+        int32_t hx,hy,ix,iy;
+        u_int32_t lx,ly;
+
+        EXTRACT_WORDS(hx,lx,x);
+        EXTRACT_WORDS(hy,ly,y);
+        ix = hx&0x7fffffff;             // |x| 
+        iy = hy&0x7fffffff;             // |y| 
+
+        if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   // x is nan
+           ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))     // y is nan
+           return x+y;
+        if(x==y) return y;              // x=y, return y
+        if((ix|lx)==0) {                        // x == 0 
+            INSERT_WORDS(x,hy&0x80000000,1);    // return +-minsubnormal
+            t = x*x;
+            if(t==x) return t; else return x;   // raise underflow flag 
+        }
+        if(hx>=0) {                             // x > 0 
+            if(hx>hy||((hx==hy)&&(lx>ly))) {    // x > y, x -= ulp 
+                if(lx==0) hx -= 1;
+                lx -= 1;
+            } else {                            // x < y, x += ulp
+                lx += 1;
+                if(lx==0) hx += 1;
+            }
+        } else {                                // x < 0 
+            if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){// x < y, x -= ulp
+                if(lx==0) hx -= 1;
+                lx -= 1;
+            } else {                            // x > y, x += ulp
+                lx += 1;
+                if(lx==0) hx += 1;
+            }
+        }
+        hy = hx&0x7ff00000;
+        if(hy>=0x7ff00000) return x+x;  // overflow
+        if(hy<0x00100000) {             // underflow
+            t = x*x;
+            if(t!=x) {          // raise underflow flag
+                INSERT_WORDS(y,hx,lx);
+                return y;
+            }
+        }
+        INSERT_WORDS(x,hx,lx);
+        return x;
+}
+*/
+
 #if(GLM_COMPILER & GLM_COMPILER_VC)
 #	if(GLM_MODEL == GLM_MODEL_32)
 #		define GLM_NEXT_AFTER_FLT(x, toward) (float)_nextafter(x, float(toward))