]> www.ginac.de Git - cln.git/blobdiff - src/float/conv/cl_FF_to_double.cc
Initial revision
[cln.git] / src / float / conv / cl_FF_to_double.cc
diff --git a/src/float/conv/cl_FF_to_double.cc b/src/float/conv/cl_FF_to_double.cc
new file mode 100644 (file)
index 0000000..34f50c2
--- /dev/null
@@ -0,0 +1,64 @@
+// cl_FF_to_double().
+
+// General includes.
+#include "cl_sysdep.h"
+
+// Specification.
+#include "cl_ffloat.h"
+
+
+// Implementation.
+
+#include "cl_FF.h"
+#include "cl_DF.h"
+
+double cl_double_approx (const cl_FF& x)
+{
+       // x entpacken:
+       var cl_signean sign;
+       var sintL exp;
+       var uint32 mant;
+       FF_decode(x, { return 0.0; }, sign=,exp=,mant=);
+       // Mantisse um 52-23=29 Nullbits erweitern:
+       union { dfloat eksplicit; double machine_double; } u;
+       #if (cl_word_size==64)
+       if (((sintL)(FF_exp_high-FF_exp_mid) > (sintL)(DF_exp_high-DF_exp_mid))
+           && (exp > (sintL)(DF_exp_high-DF_exp_mid)))
+         { u.eksplicit =
+               ((sint64)sign & bit(63))
+             | ((uint64)(bit(DF_exp_len)-1) << DF_mant_len); // Infinity
+         }
+       else
+       if (((sintL)(FF_exp_low-FF_exp_mid) < (sintL)(DF_exp_low-DF_exp_mid))
+           && (exp < (sintL)(DF_exp_low-DF_exp_mid)))
+         { u.eksplicit = ((sint64)sign & bit(63)); } // 0.0
+       else
+         { u.eksplicit =
+               ((sint64)sign & bit(63))                  /* Vorzeichen */
+             | ((uint64)(exp+DF_exp_mid) << DF_mant_len) /* Exponent   */
+             | (((uint64)mant<<(DF_mant_len-FF_mant_len)) & (bit(DF_mant_len)-1)); /* Mantisse   */
+         }
+       #else
+       if (((sintL)(FF_exp_high-FF_exp_mid) > (sintL)(DF_exp_high-DF_exp_mid))
+           && (exp > (sintL)(DF_exp_high-DF_exp_mid)))
+         { u.eksplicit.semhi =
+               ((sint32)sign & bit(31))
+             | ((uint32)(bit(DF_exp_len)-1) << (DF_mant_len-32)); // Infinity
+           u.eksplicit.mlo = 0;
+         }
+       else
+       if (((sintL)(FF_exp_low-FF_exp_mid) < (sintL)(DF_exp_low-DF_exp_mid))
+           && (exp < (sintL)(DF_exp_low-DF_exp_mid)))
+         { u.eksplicit.semhi = ((sint32)sign & bit(31)); // 0.0
+           u.eksplicit.mlo = 0;
+         }
+       else
+         { u.eksplicit.semhi =
+               ((sint32)sign & bit(31))                       /* Vorzeichen */
+             | ((uint32)(exp+DF_exp_mid) << (DF_mant_len-32)) /* Exponent   */
+             | (((uint32)mant>>(32-(DF_mant_len-FF_mant_len))) & (bit(DF_mant_len-32)-1)); /* Mantisse   */
+           u.eksplicit.mlo = mant<<(DF_mant_len-FF_mant_len);
+         }
+       #endif
+       return u.machine_double;
+}