/*************************************************************************** * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and * * Martin Renou * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XSIMD_FP_SIGN_HPP #define XSIMD_FP_SIGN_HPP #include #include "xsimd_numerical_constant.hpp" namespace xsimd { template batch_type_t bitofsign(const simd_base& x); template batch_type_t copysign(const simd_base& x1, const simd_base& x2); template batch_type_t sign(const simd_base& x); template batch_type_t signnz(const simd_base& x); /************************** * fp_sign implementation * **************************/ template inline batch_type_t bitofsign(const simd_base& x) { return x() & minuszero>(); } template inline batch_type_t copysign(const simd_base& x1, const simd_base& x2) { return abs(x1) | bitofsign(x2); } /*********************** * sign implementation * ***********************/ namespace detail { /* origin: boost/simd/arch/common/simd/function/sign.hpp */ /* * ==================================================== * copyright 2016 NumScale SAS * * Distributed under the Boost Software License, Version 1.0. * (See copy at http://boost.org/LICENSE_1_0.txt) * ==================================================== */ template ::value> struct sign_impl { static inline B compute(const B& a) { return select(a > zero(), B(1), zero()) - select(a < zero(), B(1), zero()); } }; template struct sign_impl { static inline B compute(const B& a) { B r = select(a > B(0.), B(1.), B(0.)) - select(a < B(0.), B(1.), B(0.)); #ifdef XSIMD_NO_NANS return r; #else return select(xsimd::isnan(a), nan(), r); #endif } }; } template inline batch_type_t sign(const simd_base& x) { return detail::sign_impl>::compute(x()); } /************************* * signnz implementation * *************************/ namespace detail { /* origin: boost/simd/arch/common/simd/function/signnz.hpp */ /* * ==================================================== * copyright 2016 NumScale SAS * * Distributed under the Boost Software License, Version 1.0. * (See copy at http://boost.org/LICENSE_1_0.txt) * ==================================================== */ template ::value> struct signnz_impl { static inline B compute(const B& x) { using value_type = typename B::value_type; return (x >> (sizeof(value_type) * 8 - 1)) | B(1.); } }; template struct signnz_impl { static inline B compute(const B& x) { #ifndef XSIMD_NO_NANS return select(xsimd::isnan(x), nan(), B(1.) | (signmask() & x)); #else return B(1.) | (signmask() & x); #endif } }; } template inline batch_type_t signnz(const simd_base& x) { return detail::signnz_impl>::compute(x()); } } #endif