1 | /*************************************************************************** |
2 | * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and * |
3 | * Martin Renou * |
4 | * Copyright (c) QuantStack * |
5 | * Copyright (c) Serge Guelton * |
6 | * * |
7 | * Distributed under the terms of the BSD 3-Clause License. * |
8 | * * |
9 | * The full license is in the file LICENSE, distributed with this software. * |
10 | ****************************************************************************/ |
11 | |
12 | #ifndef XSIMD_GENERIC_ROUNDING_HPP |
13 | #define XSIMD_GENERIC_ROUNDING_HPP |
14 | |
15 | #include "./xsimd_generic_details.hpp" |
16 | |
17 | namespace xsimd |
18 | { |
19 | |
20 | namespace kernel |
21 | { |
22 | |
23 | using namespace types; |
24 | |
25 | // ceil |
26 | template <class A, class T> |
27 | inline batch<T, A> ceil(batch<T, A> const& self, requires_arch<generic>) noexcept |
28 | { |
29 | batch<T, A> truncated_self = trunc(self); |
30 | return select(truncated_self < self, truncated_self + 1, truncated_self); |
31 | } |
32 | |
33 | // floor |
34 | template <class A, class T> |
35 | inline batch<T, A> floor(batch<T, A> const& self, requires_arch<generic>) noexcept |
36 | { |
37 | batch<T, A> truncated_self = trunc(self); |
38 | return select(truncated_self > self, truncated_self - 1, truncated_self); |
39 | } |
40 | |
41 | // round |
42 | template <class A, class T> |
43 | inline batch<T, A> round(batch<T, A> const& self, requires_arch<generic>) noexcept |
44 | { |
45 | auto v = abs(self); |
46 | auto c = ceil(v); |
47 | auto cp = select(c - 0.5 > v, c - 1, c); |
48 | return select(v > constants::maxflint<batch<T, A>>(), self, copysign(cp, self)); |
49 | } |
50 | |
51 | // trunc |
52 | template <class A, class T, class = typename std::enable_if<std::is_integral<T>::value, void>::type> |
53 | inline batch<T, A> trunc(batch<T, A> const& self, requires_arch<generic>) noexcept |
54 | { |
55 | return self; |
56 | } |
57 | template <class A> |
58 | inline batch<float, A> trunc(batch<float, A> const& self, requires_arch<generic>) noexcept |
59 | { |
60 | return select(abs(self) < constants::maxflint<batch<float, A>>(), to_float(to_int(self)), self); |
61 | } |
62 | template <class A> |
63 | inline batch<double, A> trunc(batch<double, A> const& self, requires_arch<generic>) noexcept |
64 | { |
65 | return select(abs(self) < constants::maxflint<batch<double, A>>(), to_float(to_int(self)), self); |
66 | } |
67 | |
68 | } |
69 | |
70 | } |
71 | |
72 | #endif |
73 | |