From fcebef6fa12d24fd92fdd30f9a89632fbd5c3e1f Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Mon, 30 Apr 2012 12:01:19 +0200 Subject: [PATCH] Fix Pow(const C4Real&, const C4Real&) --- src/lib/C4Real.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/lib/C4Real.cpp b/src/lib/C4Real.cpp index eea2a81e1..222a61732 100755 --- a/src/lib/C4Real.cpp +++ b/src/lib/C4Real.cpp @@ -101,11 +101,13 @@ C4Real Pow(const C4Real &x, const C4Real &y) val.value = exp_ps(val.value); if(sign) { - val.value = _mm_or_ps(x.value, C4Real::float_hexconst(0x80000000)); - return val; + // smart little hack: concatenate like in operator%=, but one bit more + __m128 sig = _mm_or_ps(_mm_and_ps(y.value, C4Real::float_hexconst(0x80000000)), C4Real::float_hexconst(0x4b800000)); + __m128 trunc = _mm_sub_ps(_mm_add_ps(y.value, sig), sig); + if(_mm_comineq_ss(y.value, trunc)) // negate result if power is not even + val.value = _mm_or_ps(x.value, C4Real::float_hexconst(0x80000000)); } - else - return val; + return val; } C4Real Sqrt(const C4Real &v) @@ -146,4 +148,4 @@ C4Real Atan2(const C4Real & y, const C4Real & x) C4Real ret; ret.value = _mm_mul_ps(t3, _mm_div_ss(C4Real::float_hexconst(0x43340000), C4Real(C4Real::PI).value)); return ret; -} \ No newline at end of file +}