summaryrefslogtreecommitdiffstats
path: root/mathfuncs_convert.h
diff options
context:
space:
mode:
authorErik Schnetter <schnetter@gmail.com>2012-11-30 15:50:03 -0500
committerErik Schnetter <schnetter@gmail.com>2012-11-30 15:50:03 -0500
commitd2614759a1d542c41af59b04d8711246d2a1e876 (patch)
tree2689209034d9ccc3d29208d50b82b4f89116aa1b /mathfuncs_convert.h
downloadvecmathlib-d2614759a1d542c41af59b04d8711246d2a1e876.zip
vecmathlib-d2614759a1d542c41af59b04d8711246d2a1e876.tar.gz
Import initial version
Diffstat (limited to 'mathfuncs_convert.h')
-rw-r--r--mathfuncs_convert.h86
1 files changed, 86 insertions, 0 deletions
diff --git a/mathfuncs_convert.h b/mathfuncs_convert.h
new file mode 100644
index 0000000..4dfffef
--- /dev/null
+++ b/mathfuncs_convert.h
@@ -0,0 +1,86 @@
+// -*-C++-*-
+
+#ifndef MATHFUNCS_CONVERT_H
+#define MATHFUNCS_CONVERT_H
+
+#include "mathfuncs_base.h"
+
+#include <cassert>
+#include <cmath>
+
+
+
+namespace vecmathlib {
+
+ template<typename realvec_t>
+ realvec_t mathfuncs<realvec_t>::vml_convert_float(intvec_t x)
+ {
+ // Convert in two passes. Convert as much as possible during the
+ // first pass (lobits), so that the second pass (hibits) may be
+ // omitted if the high bits are known to be zero.
+ int_t lobits = FP::mantissa_bits;
+ int_t hibits = FP::bits - lobits;
+
+ // Convert lower bits
+ intvec_t xlo = x & IV((U(1) << lobits) - 1);
+ // exponent for the equivalent floating point number
+ int_t exponent_lo = FP::exponent_offset + lobits;
+ xlo |= exponent_lo;
+ // subtract hidden mantissa bit
+ realvec_t flo = as_float(xlo) - RV(FP::as_float(exponent_lo));
+
+ // Convert upper bits
+ // make unsigned by subtracting largest negative number
+ x ^= FP::sign_mask;
+ intvec_t xhi = lsr(x, lobits);
+ // exponent for the equivalent floating point number
+ int_t exponent_hi = FP::exponent_offset + FP::bits;
+ xhi |= exponent_hi;
+ // add largest negative number, and subtract hidden mantissa bit
+ realvec_t
+ fhi = as_float(xhi) - RV(FP::as_float(exponent_hi) + R(FP::sign_mask));
+
+ // Combine results
+ return flo + fhi;
+ }
+
+
+
+ template<typename realvec_t>
+ auto mathfuncs<realvec_t>::vml_convert_int(realvec_t x) -> intvec_t
+ {
+ // Handle zero
+ boolvec_t is_zero = x == RV(0.0);
+ // Handle negative numbers
+ boolvec_t is_negative = signbit(x);
+ x = fabs(x);
+
+ // Round, by adding a large number that removes the excess
+ // precision
+ int_t large = U(1) << FP::mantissa_bits;
+ x += R(large);
+
+ intvec_t exponent = ilogb(x);
+ for (int i=0; i<intvec_t::size; ++i) {
+ assert(exponent[i] >= FP::mantissa_bits);
+ }
+ intvec_t ix = as_int(x) & IV(FP::mantissa_mask);
+ // add hidden mantissa bit
+ ix |= U(1) << FP::mantissa_bits;
+ // shift according to exponent
+ ix <<= exponent - IV(FP::mantissa_bits);
+
+ // Undo the adding above
+ ix -= large;
+
+ // Handle negative numbers
+ ix = ifthen(is_negative, -ix, ix);
+ // Handle zero
+ ix = ifthen(is_zero, IV(0), ix);
+
+ return ix;
+ }
+
+}; // namespace vecmathlib
+
+#endif // #ifndef MATHFUNCS_CONVERT_H
OpenPOWER on IntegriCloud