fixed_point.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020-2022, NVIDIA CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <cudf/detail/utilities/assert.cuh>
20 #include <cudf/fixed_point/temporary.hpp>
21 #include <cudf/types.hpp>
22 
23 // Note: The <cuda/std/*> versions are used in order for Jitify to work with our fixed_point type.
24 // Jitify is needed for several algorithms (binaryop, rolling, etc)
25 #include <cuda/std/limits>
26 #include <cuda/std/type_traits> // add cuda namespace
27 
28 #include <algorithm>
29 #include <cassert>
30 #include <cmath>
31 #include <string>
32 
34 namespace numeric {
35 
36 enum scale_type : int32_t {};
37 
47 enum class Radix : int32_t { BASE_2 = 2, BASE_10 = 10 };
48 
49 template <typename T>
50 constexpr inline auto is_supported_representation_type()
51 {
52  return cuda::std::is_same_v<T, int32_t> || //
53  cuda::std::is_same_v<T, int64_t> || //
54  cuda::std::is_same_v<T, __int128_t>;
55 }
56 
57 template <typename T>
58 constexpr inline auto is_supported_construction_value_type()
59 {
60  return cuda::std::is_integral<T>() || cuda::std::is_floating_point_v<T>;
61 }
62 
63 // Helper functions for `fixed_point` type
64 namespace detail {
77 template <typename Rep,
78  Radix Base,
79  typename T,
80  typename cuda::std::enable_if_t<(cuda::std::is_same_v<int32_t, T> &&
81  is_supported_representation_type<Rep>())>* = nullptr>
82 CUDF_HOST_DEVICE inline Rep ipow(T exponent)
83 {
84  cudf_assert(exponent >= 0 && "integer exponentiation with negative exponent is not possible.");
85  if (exponent == 0) { return static_cast<Rep>(1); }
86 
87  auto extra = static_cast<Rep>(1);
88  auto square = static_cast<Rep>(Base);
89  while (exponent > 1) {
90  if (exponent & 1 /* odd */) {
91  extra *= square;
92  exponent -= 1;
93  }
94  exponent /= 2;
95  square *= square;
96  }
97  return square * extra;
98 }
99 
111 template <typename Rep, Radix Rad, typename T>
112 CUDF_HOST_DEVICE inline constexpr T right_shift(T const& val, scale_type const& scale)
113 {
114  return val / ipow<Rep, Rad>(static_cast<int32_t>(scale));
115 }
116 
128 template <typename Rep, Radix Rad, typename T>
129 CUDF_HOST_DEVICE inline constexpr T left_shift(T const& val, scale_type const& scale)
130 {
131  return val * ipow<Rep, Rad>(static_cast<int32_t>(-scale));
132 }
133 
147 template <typename Rep, Radix Rad, typename T>
148 CUDF_HOST_DEVICE inline constexpr T shift(T const& val, scale_type const& scale)
149 {
150  if (scale == 0) { return val; }
151  if (scale > 0) { return right_shift<Rep, Rad>(val, scale); }
152  return left_shift<Rep, Rad>(val, scale);
153 }
154 
155 } // namespace detail
156 
175 template <typename Rep,
176  typename cuda::std::enable_if_t<is_supported_representation_type<Rep>()>* = nullptr>
178  Rep value;
179  scale_type scale;
180  CUDF_HOST_DEVICE inline explicit scaled_integer(Rep v, scale_type s) : value{v}, scale{s} {}
181 };
182 
192 template <typename Rep, Radix Rad>
193 class fixed_point {
194  Rep _value{};
195  scale_type _scale;
196 
197  public:
198  using rep = Rep;
199 
208  template <typename T,
209  typename cuda::std::enable_if_t<cuda::std::is_floating_point<T>() &&
210  is_supported_representation_type<Rep>()>* = nullptr>
211  CUDF_HOST_DEVICE inline explicit fixed_point(T const& value, scale_type const& scale)
212  : _value{static_cast<Rep>(detail::shift<Rep, Rad>(value, scale))}, _scale{scale}
213  {
214  }
215 
224  template <typename T,
225  typename cuda::std::enable_if_t<cuda::std::is_integral<T>() &&
226  is_supported_representation_type<Rep>()>* = nullptr>
227  CUDF_HOST_DEVICE inline explicit fixed_point(T const& value, scale_type const& scale)
228  // `value` is cast to `Rep` to avoid overflow in cases where
229  // constructing to `Rep` that is wider than `T`
230  : _value{detail::shift<Rep, Rad>(static_cast<Rep>(value), scale)}, _scale{scale}
231  {
232  }
233 
239  CUDF_HOST_DEVICE inline explicit fixed_point(scaled_integer<Rep> s)
240  : _value{s.value}, _scale{s.scale}
241  {
242  }
243 
248  template <typename T,
249  typename cuda::std::enable_if_t<is_supported_construction_value_type<T>()>* = nullptr>
250  CUDF_HOST_DEVICE inline fixed_point(T const& value)
251  : _value{static_cast<Rep>(value)}, _scale{scale_type{0}}
252  {
253  }
254 
259  CUDF_HOST_DEVICE inline fixed_point() : _scale{scale_type{0}} {}
260 
267  template <typename U,
268  typename cuda::std::enable_if_t<cuda::std::is_floating_point_v<U>>* = nullptr>
269  explicit constexpr operator U() const
270  {
271  return detail::shift<Rep, Rad>(static_cast<U>(_value), scale_type{-_scale});
272  }
273 
280  template <typename U, typename cuda::std::enable_if_t<cuda::std::is_integral_v<U>>* = nullptr>
281  explicit constexpr operator U() const
282  {
283  // Cast to the larger of the two types (of U and Rep) before converting to Rep because in
284  // certain cases casting to U before shifting will result in integer overflow (i.e. if U =
285  // int32_t, Rep = int64_t and _value > 2 billion)
286  auto const value = std::common_type_t<U, Rep>(_value);
287  return static_cast<U>(detail::shift<Rep, Rad>(value, scale_type{-_scale}));
288  }
289 
290  CUDF_HOST_DEVICE inline operator scaled_integer<Rep>() const
291  {
292  return scaled_integer<Rep>{_value, _scale};
293  }
294 
300  CUDF_HOST_DEVICE inline rep value() const { return _value; }
301 
307  CUDF_HOST_DEVICE inline scale_type scale() const { return _scale; }
308 
314  CUDF_HOST_DEVICE inline explicit constexpr operator bool() const
315  {
316  return static_cast<bool>(_value);
317  }
318 
326  template <typename Rep1, Radix Rad1>
327  CUDF_HOST_DEVICE inline fixed_point<Rep1, Rad1>& operator+=(fixed_point<Rep1, Rad1> const& rhs)
328  {
329  *this = *this + rhs;
330  return *this;
331  }
332 
340  template <typename Rep1, Radix Rad1>
341  CUDF_HOST_DEVICE inline fixed_point<Rep1, Rad1>& operator*=(fixed_point<Rep1, Rad1> const& rhs)
342  {
343  *this = *this * rhs;
344  return *this;
345  }
346 
354  template <typename Rep1, Radix Rad1>
355  CUDF_HOST_DEVICE inline fixed_point<Rep1, Rad1>& operator-=(fixed_point<Rep1, Rad1> const& rhs)
356  {
357  *this = *this - rhs;
358  return *this;
359  }
360 
368  template <typename Rep1, Radix Rad1>
369  CUDF_HOST_DEVICE inline fixed_point<Rep1, Rad1>& operator/=(fixed_point<Rep1, Rad1> const& rhs)
370  {
371  *this = *this / rhs;
372  return *this;
373  }
374 
380  CUDF_HOST_DEVICE inline fixed_point<Rep, Rad>& operator++()
381  {
382  *this = *this + fixed_point<Rep, Rad>{1, scale_type{_scale}};
383  return *this;
384  }
385 
397  template <typename Rep1, Radix Rad1>
398  CUDF_HOST_DEVICE inline friend fixed_point<Rep1, Rad1> operator+(
399  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
400 
412  template <typename Rep1, Radix Rad1>
413  CUDF_HOST_DEVICE inline friend fixed_point<Rep1, Rad1> operator-(
414  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
415 
425  template <typename Rep1, Radix Rad1>
426  CUDF_HOST_DEVICE inline friend fixed_point<Rep1, Rad1> operator*(
427  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
428 
438  template <typename Rep1, Radix Rad1>
439  CUDF_HOST_DEVICE inline friend fixed_point<Rep1, Rad1> operator/(
440  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
441 
453  template <typename Rep1, Radix Rad1>
454  CUDF_HOST_DEVICE inline friend fixed_point<Rep1, Rad1> operator%(
455  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
456 
468  template <typename Rep1, Radix Rad1>
469  CUDF_HOST_DEVICE inline friend bool operator==(fixed_point<Rep1, Rad1> const& lhs,
470  fixed_point<Rep1, Rad1> const& rhs);
471 
483  template <typename Rep1, Radix Rad1>
484  CUDF_HOST_DEVICE inline friend bool operator!=(fixed_point<Rep1, Rad1> const& lhs,
485  fixed_point<Rep1, Rad1> const& rhs);
486 
498  template <typename Rep1, Radix Rad1>
499  CUDF_HOST_DEVICE inline friend bool operator<=(fixed_point<Rep1, Rad1> const& lhs,
500  fixed_point<Rep1, Rad1> const& rhs);
501 
513  template <typename Rep1, Radix Rad1>
514  CUDF_HOST_DEVICE inline friend bool operator>=(fixed_point<Rep1, Rad1> const& lhs,
515  fixed_point<Rep1, Rad1> const& rhs);
516 
528  template <typename Rep1, Radix Rad1>
529  CUDF_HOST_DEVICE inline friend bool operator<(fixed_point<Rep1, Rad1> const& lhs,
530  fixed_point<Rep1, Rad1> const& rhs);
531 
543  template <typename Rep1, Radix Rad1>
544  CUDF_HOST_DEVICE inline friend bool operator>(fixed_point<Rep1, Rad1> const& lhs,
545  fixed_point<Rep1, Rad1> const& rhs);
546 
556  CUDF_HOST_DEVICE inline fixed_point<Rep, Rad> rescaled(scale_type scale) const
557  {
558  if (scale == _scale) { return *this; }
559  Rep const value = detail::shift<Rep, Rad>(_value, scale_type{scale - _scale});
561  }
562 
566  explicit operator std::string() const
567  {
568  if (_scale < 0) {
569  auto const av = detail::abs(_value);
570  Rep const n = detail::exp10<Rep>(-_scale);
571  Rep const f = av % n;
572  auto const num_zeros =
573  std::max(0, (-_scale - static_cast<int32_t>(detail::to_string(f).size())));
574  auto const zeros = std::string(num_zeros, '0');
575  auto const sign = _value < 0 ? std::string("-") : std::string();
576  return sign + detail::to_string(av / n) + std::string(".") + zeros +
577  detail::to_string(av % n);
578  }
579  auto const zeros = std::string(_scale, '0');
580  return detail::to_string(_value) + zeros;
581  }
582 };
583 
593 template <typename Rep, typename T>
594 CUDF_HOST_DEVICE inline auto addition_overflow(T lhs, T rhs)
595 {
596  return rhs > 0 ? lhs > cuda::std::numeric_limits<Rep>::max() - rhs
597  : lhs < cuda::std::numeric_limits<Rep>::min() - rhs;
598 }
599 
608 template <typename Rep, typename T>
609 CUDF_HOST_DEVICE inline auto subtraction_overflow(T lhs, T rhs)
610 {
611  return rhs > 0 ? lhs < cuda::std::numeric_limits<Rep>::min() + rhs
612  : lhs > cuda::std::numeric_limits<Rep>::max() + rhs;
613 }
614 
623 template <typename Rep, typename T>
624 CUDF_HOST_DEVICE inline auto division_overflow(T lhs, T rhs)
625 {
626  return lhs == cuda::std::numeric_limits<Rep>::min() && rhs == -1;
627 }
628 
637 template <typename Rep, typename T>
638 CUDF_HOST_DEVICE inline auto multiplication_overflow(T lhs, T rhs)
639 {
640  auto const min = cuda::std::numeric_limits<Rep>::min();
641  auto const max = cuda::std::numeric_limits<Rep>::max();
642  if (rhs > 0) { return lhs > max / rhs || lhs < min / rhs; }
643  if (rhs < -1) { return lhs > min / rhs || lhs < max / rhs; }
644  return rhs == -1 && lhs == min;
645 }
646 
647 // PLUS Operation
648 template <typename Rep1, Radix Rad1>
649 CUDF_HOST_DEVICE inline fixed_point<Rep1, Rad1> operator+(fixed_point<Rep1, Rad1> const& lhs,
650  fixed_point<Rep1, Rad1> const& rhs)
651 {
652  auto const scale = std::min(lhs._scale, rhs._scale);
653  auto const sum = lhs.rescaled(scale)._value + rhs.rescaled(scale)._value;
654 
655 #if defined(__CUDACC_DEBUG__)
656 
657  assert(!addition_overflow<Rep1>(lhs.rescaled(scale)._value, rhs.rescaled(scale)._value) &&
658  "fixed_point overflow");
659 
660 #endif
661 
662  return fixed_point<Rep1, Rad1>{scaled_integer<Rep1>{sum, scale}};
663 }
664 
665 // MINUS Operation
666 template <typename Rep1, Radix Rad1>
667 CUDF_HOST_DEVICE inline fixed_point<Rep1, Rad1> operator-(fixed_point<Rep1, Rad1> const& lhs,
668  fixed_point<Rep1, Rad1> const& rhs)
669 {
670  auto const scale = std::min(lhs._scale, rhs._scale);
671  auto const diff = lhs.rescaled(scale)._value - rhs.rescaled(scale)._value;
672 
673 #if defined(__CUDACC_DEBUG__)
674 
675  assert(!subtraction_overflow<Rep1>(lhs.rescaled(scale)._value, rhs.rescaled(scale)._value) &&
676  "fixed_point overflow");
677 
678 #endif
679 
680  return fixed_point<Rep1, Rad1>{scaled_integer<Rep1>{diff, scale}};
681 }
682 
683 // MULTIPLIES Operation
684 template <typename Rep1, Radix Rad1>
685 CUDF_HOST_DEVICE inline fixed_point<Rep1, Rad1> operator*(fixed_point<Rep1, Rad1> const& lhs,
686  fixed_point<Rep1, Rad1> const& rhs)
687 {
688 #if defined(__CUDACC_DEBUG__)
689 
690  assert(!multiplication_overflow<Rep1>(lhs._value, rhs._value) && "fixed_point overflow");
691 
692 #endif
693 
695  scaled_integer<Rep1>(lhs._value * rhs._value, scale_type{lhs._scale + rhs._scale})};
696 }
697 
698 // DIVISION Operation
699 template <typename Rep1, Radix Rad1>
700 CUDF_HOST_DEVICE inline fixed_point<Rep1, Rad1> operator/(fixed_point<Rep1, Rad1> const& lhs,
701  fixed_point<Rep1, Rad1> const& rhs)
702 {
703 #if defined(__CUDACC_DEBUG__)
704 
705  assert(!division_overflow<Rep1>(lhs._value, rhs._value) && "fixed_point overflow");
706 
707 #endif
708 
710  scaled_integer<Rep1>(lhs._value / rhs._value, scale_type{lhs._scale - rhs._scale})};
711 }
712 
713 // EQUALITY COMPARISON Operation
714 template <typename Rep1, Radix Rad1>
715 CUDF_HOST_DEVICE inline bool operator==(fixed_point<Rep1, Rad1> const& lhs,
716  fixed_point<Rep1, Rad1> const& rhs)
717 {
718  auto const scale = std::min(lhs._scale, rhs._scale);
719  return lhs.rescaled(scale)._value == rhs.rescaled(scale)._value;
720 }
721 
722 // EQUALITY NOT COMPARISON Operation
723 template <typename Rep1, Radix Rad1>
724 CUDF_HOST_DEVICE inline bool operator!=(fixed_point<Rep1, Rad1> const& lhs,
725  fixed_point<Rep1, Rad1> const& rhs)
726 {
727  auto const scale = std::min(lhs._scale, rhs._scale);
728  return lhs.rescaled(scale)._value != rhs.rescaled(scale)._value;
729 }
730 
731 // LESS THAN OR EQUAL TO Operation
732 template <typename Rep1, Radix Rad1>
733 CUDF_HOST_DEVICE inline bool operator<=(fixed_point<Rep1, Rad1> const& lhs,
734  fixed_point<Rep1, Rad1> const& rhs)
735 {
736  auto const scale = std::min(lhs._scale, rhs._scale);
737  return lhs.rescaled(scale)._value <= rhs.rescaled(scale)._value;
738 }
739 
740 // GREATER THAN OR EQUAL TO Operation
741 template <typename Rep1, Radix Rad1>
742 CUDF_HOST_DEVICE inline bool operator>=(fixed_point<Rep1, Rad1> const& lhs,
743  fixed_point<Rep1, Rad1> const& rhs)
744 {
745  auto const scale = std::min(lhs._scale, rhs._scale);
746  return lhs.rescaled(scale)._value >= rhs.rescaled(scale)._value;
747 }
748 
749 // LESS THAN Operation
750 template <typename Rep1, Radix Rad1>
751 CUDF_HOST_DEVICE inline bool operator<(fixed_point<Rep1, Rad1> const& lhs,
752  fixed_point<Rep1, Rad1> const& rhs)
753 {
754  auto const scale = std::min(lhs._scale, rhs._scale);
755  return lhs.rescaled(scale)._value < rhs.rescaled(scale)._value;
756 }
757 
758 // GREATER THAN Operation
759 template <typename Rep1, Radix Rad1>
760 CUDF_HOST_DEVICE inline bool operator>(fixed_point<Rep1, Rad1> const& lhs,
761  fixed_point<Rep1, Rad1> const& rhs)
762 {
763  auto const scale = std::min(lhs._scale, rhs._scale);
764  return lhs.rescaled(scale)._value > rhs.rescaled(scale)._value;
765 }
766 
767 // MODULO OPERATION
768 template <typename Rep1, Radix Rad1>
769 CUDF_HOST_DEVICE inline fixed_point<Rep1, Rad1> operator%(fixed_point<Rep1, Rad1> const& lhs,
770  fixed_point<Rep1, Rad1> const& rhs)
771 {
772  auto const scale = std::min(lhs._scale, rhs._scale);
773  auto const remainder = lhs.rescaled(scale)._value % rhs.rescaled(scale)._value;
774  return fixed_point<Rep1, Rad1>{scaled_integer<Rep1>{remainder, scale}};
775 }
776 
777 using decimal32 = fixed_point<int32_t, Radix::BASE_10>;
778 using decimal64 = fixed_point<int64_t, Radix::BASE_10>;
779 using decimal128 = fixed_point<__int128_t, Radix::BASE_10>;
780  // end of group
782 } // namespace numeric
numeric::fixed_point::rescaled
CUDF_HOST_DEVICE fixed_point< Rep, Rad > rescaled(scale_type scale) const
Method for creating a fixed_point number with a new scale
Definition: fixed_point.hpp:556
numeric::fixed_point::scale
CUDF_HOST_DEVICE scale_type scale() const
Method that returns the scale of the fixed_point number.
Definition: fixed_point.hpp:307
numeric::multiplication_overflow
CUDF_HOST_DEVICE auto multiplication_overflow(T lhs, T rhs)
Function for identifying integer overflow when multiplying.
Definition: fixed_point.hpp:638
numeric::operator>=
CUDF_HOST_DEVICE bool operator>=(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:742
numeric::fixed_point::operator==
CUDF_HOST_DEVICE friend bool operator==(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
operator == (for comparing two fixed_point numbers)
Definition: fixed_point.hpp:715
numeric::fixed_point::fixed_point
CUDF_HOST_DEVICE fixed_point()
Default constructor that constructs fixed_point number with a value and scale of zero.
Definition: fixed_point.hpp:259
numeric::Radix
Radix
Scoped enumerator to use when constructing fixed_point
Definition: fixed_point.hpp:47
numeric::fixed_point::operator-
CUDF_HOST_DEVICE friend fixed_point< Rep1, Rad1 > operator-(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
operator - (for subtracting two fixed_point numbers)
Definition: fixed_point.hpp:667
numeric::fixed_point::operator+=
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > & operator+=(fixed_point< Rep1, Rad1 > const &rhs)
operator +=
Definition: fixed_point.hpp:327
numeric::operator+
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > operator+(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:649
numeric::fixed_point
A type for representing a number with a fixed amount of precision.
Definition: fixed_point.hpp:193
numeric::operator/
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > operator/(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:700
types.hpp
Type declarations for libcudf.
numeric::fixed_point::operator!=
CUDF_HOST_DEVICE friend bool operator!=(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
operator != (for comparing two fixed_point numbers)
Definition: fixed_point.hpp:724
numeric::fixed_point::operator/=
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > & operator/=(fixed_point< Rep1, Rad1 > const &rhs)
operator /=
Definition: fixed_point.hpp:369
numeric::fixed_point::operator++
CUDF_HOST_DEVICE fixed_point< Rep, Rad > & operator++()
operator ++ (post-increment)
Definition: fixed_point.hpp:380
numeric::detail::left_shift
constexpr CUDF_HOST_DEVICE T left_shift(T const &val, scale_type const &scale)
Function that performs a left shift scale "times" on the val
Definition: fixed_point.hpp:129
numeric::detail::ipow
CUDF_HOST_DEVICE Rep ipow(T exponent)
A function for integer exponentiation by squaring.
Definition: fixed_point.hpp:82
numeric::fixed_point::operator>
CUDF_HOST_DEVICE friend bool operator>(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
operator > (for comparing two fixed_point numbers)
Definition: fixed_point.hpp:760
numeric::fixed_point::operator*=
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > & operator*=(fixed_point< Rep1, Rad1 > const &rhs)
operator *=
Definition: fixed_point.hpp:341
numeric::fixed_point::operator/
CUDF_HOST_DEVICE friend fixed_point< Rep1, Rad1 > operator/(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
operator / (for dividing two fixed_point numbers)
Definition: fixed_point.hpp:700
numeric::subtraction_overflow
CUDF_HOST_DEVICE auto subtraction_overflow(T lhs, T rhs)
Function for identifying integer overflow when subtracting.
Definition: fixed_point.hpp:609
numeric::operator*
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > operator*(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:685
numeric::fixed_point::operator%
CUDF_HOST_DEVICE friend fixed_point< Rep1, Rad1 > operator%(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
operator % (for computing the modulo operation of two fixed_point numbers)
Definition: fixed_point.hpp:769
numeric::scaled_integer
Helper struct for constructing fixed_point when value is already shifted.
Definition: fixed_point.hpp:177
numeric::fixed_point::operator+
CUDF_HOST_DEVICE friend fixed_point< Rep1, Rad1 > operator+(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
operator + (for adding two fixed_point numbers)
Definition: fixed_point.hpp:649
numeric::addition_overflow
CUDF_HOST_DEVICE auto addition_overflow(T lhs, T rhs)
Function for identifying integer overflow when adding.
Definition: fixed_point.hpp:594
numeric::operator-
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > operator-(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:667
numeric::division_overflow
CUDF_HOST_DEVICE auto division_overflow(T lhs, T rhs)
Function for identifying integer overflow when dividing.
Definition: fixed_point.hpp:624
numeric::operator>
CUDF_HOST_DEVICE bool operator>(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:760
numeric::detail::right_shift
constexpr CUDF_HOST_DEVICE T right_shift(T const &val, scale_type const &scale)
Function that performs a right shift scale "times" on the val
Definition: fixed_point.hpp:112
numeric::fixed_point::operator>=
CUDF_HOST_DEVICE friend bool operator>=(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
operator >= (for comparing two fixed_point numbers)
Definition: fixed_point.hpp:742
numeric::fixed_point::operator<
CUDF_HOST_DEVICE friend bool operator<(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
operator < (for comparing two fixed_point numbers)
Definition: fixed_point.hpp:751
numeric::fixed_point::value
CUDF_HOST_DEVICE rep value() const
Method that returns the underlying value of the fixed_point number.
Definition: fixed_point.hpp:300
numeric::fixed_point::operator-=
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > & operator-=(fixed_point< Rep1, Rad1 > const &rhs)
operator -=
Definition: fixed_point.hpp:355
numeric::fixed_point::operator<=
CUDF_HOST_DEVICE friend bool operator<=(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
operator <= (for comparing two fixed_point numbers)
Definition: fixed_point.hpp:733
numeric::operator==
CUDF_HOST_DEVICE bool operator==(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:715
numeric::fixed_point::operator*
CUDF_HOST_DEVICE friend fixed_point< Rep1, Rad1 > operator*(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
operator * (for multiplying two fixed_point numbers)
Definition: fixed_point.hpp:685
numeric::operator<
CUDF_HOST_DEVICE bool operator<(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:751
numeric::operator%
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > operator%(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:769
numeric::operator<=
CUDF_HOST_DEVICE bool operator<=(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:733
numeric
fixed_point and supporting types
Definition: fixed_point.hpp:34
numeric::operator!=
CUDF_HOST_DEVICE bool operator!=(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:724