fixed_point.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020-2021, 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/types.hpp>
21 
22 // Note: The <cuda/std/*> versions are used in order for Jitify to work with our fixed_point type.
23 // Jitify is needed for several algorithms (binaryop, rolling, etc)
24 #include <cuda/std/limits>
25 #include <cuda/std/type_traits> // add cuda namespace
26 
27 #include <algorithm>
28 #include <cassert>
29 #include <cmath>
30 #include <string>
31 
33 namespace numeric {
35 // This is a wrapper struct that enforces "strong typing"
36 // at the construction site of the type. No implicit
37 // conversions will be allowed and you will need to use the
38 // name of the type alias (i.e. scale_type{0})
39 template <typename T>
40 struct strong_typedef {
41  T _t;
42  CUDA_HOST_DEVICE_CALLABLE explicit constexpr strong_typedef(T t) : _t(t) {}
43  CUDA_HOST_DEVICE_CALLABLE operator T() const { return _t; }
44 };
47 using scale_type = strong_typedef<int32_t>;
48 
58 enum class Radix : int32_t { BASE_2 = 2, BASE_10 = 10 };
59 
60 template <typename T>
61 constexpr inline auto is_supported_representation_type()
62 {
63  return cuda::std::is_same<T, int32_t>::value || cuda::std::is_same<T, int64_t>::value;
64 }
65 
66 template <typename T>
67 constexpr inline auto is_supported_construction_value_type()
68 {
69  return cuda::std::is_integral<T>::value || cuda::std::is_floating_point<T>::value;
70 }
71 
72 // Helper functions for `fixed_point` type
73 namespace detail {
87 template <typename Rep,
88  Radix Base,
89  typename T,
90  typename cuda::std::enable_if_t<(cuda::std::is_same<int32_t, T>::value &&
91  is_supported_representation_type<Rep>())>* = nullptr>
92 CUDA_HOST_DEVICE_CALLABLE Rep ipow(T exponent)
93 {
94  cudf_assert(exponent >= 0 && "integer exponentiation with negative exponent is not possible.");
95  if (exponent == 0) return static_cast<Rep>(1);
96  auto extra = static_cast<Rep>(1);
97  auto square = static_cast<Rep>(Base);
98  while (exponent > 1) {
99  if (exponent & 1 /* odd */) {
100  extra *= square;
101  exponent -= 1;
102  }
103  exponent /= 2;
104  square *= square;
105  }
106  return square * extra;
107 }
108 
114 CUDA_HOST_DEVICE_CALLABLE
115 auto negate(scale_type const& scale) { return scale_type{-scale}; }
116 
128 template <typename Rep, Radix Rad, typename T>
129 CUDA_HOST_DEVICE_CALLABLE constexpr T right_shift(T const& val, scale_type const& scale)
130 {
131  return val / ipow<Rep, Rad>(scale._t);
132 }
133 
145 template <typename Rep, Radix Rad, typename T>
146 CUDA_HOST_DEVICE_CALLABLE constexpr T left_shift(T const& val, scale_type const& scale)
147 {
148  return val * ipow<Rep, Rad>(-scale._t);
149 }
150 
164 template <typename Rep, Radix Rad, typename T>
165 CUDA_HOST_DEVICE_CALLABLE constexpr T shift(T const& val, scale_type const& scale)
166 {
167  if (scale == 0)
168  return val;
169  else if (scale > 0)
170  return right_shift<Rep, Rad>(val, scale);
171  else
172  return left_shift<Rep, Rad>(val, scale);
173 }
174 
175 } // namespace detail
176 
195 template <typename Rep,
196  typename cuda::std::enable_if_t<is_supported_representation_type<Rep>()>* = nullptr>
198  Rep value;
199  scale_type scale;
200  CUDA_HOST_DEVICE_CALLABLE explicit scaled_integer(Rep v, scale_type s) : value(v), scale(s) {}
201 };
202 
212 template <typename Rep, Radix Rad>
213 class fixed_point {
214  Rep _value;
215  scale_type _scale;
216 
217  public:
218  using rep = Rep;
219 
228  template <typename T,
229  typename cuda::std::enable_if_t<cuda::std::is_floating_point<T>() &&
230  is_supported_representation_type<Rep>()>* = nullptr>
231  CUDA_HOST_DEVICE_CALLABLE explicit fixed_point(T const& value, scale_type const& scale)
232  : _value{static_cast<Rep>(detail::shift<Rep, Rad>(value, scale))}, _scale{scale}
233  {
234  }
235 
244  template <typename T,
245  typename cuda::std::enable_if_t<cuda::std::is_integral<T>() &&
246  is_supported_representation_type<Rep>()>* = nullptr>
247  CUDA_HOST_DEVICE_CALLABLE explicit fixed_point(T const& value, scale_type const& scale)
248  // `value` is cast to `Rep` to avoid overflow in cases where
249  // constructing to `Rep` that is wider than `T`
250  : _value{detail::shift<Rep, Rad>(static_cast<Rep>(value), scale)}, _scale{scale}
251  {
252  }
253 
259  CUDA_HOST_DEVICE_CALLABLE
260  explicit fixed_point(scaled_integer<Rep> s) : _value{s.value}, _scale{s.scale} {}
261 
266  template <typename T,
267  typename cuda::std::enable_if_t<is_supported_construction_value_type<T>()>* = nullptr>
268  CUDA_HOST_DEVICE_CALLABLE fixed_point(T const& value)
269  : _value{static_cast<Rep>(value)}, _scale{scale_type{0}}
270  {
271  }
272 
277  CUDA_HOST_DEVICE_CALLABLE
278  fixed_point() : _value{0}, _scale{scale_type{0}} {}
279 
286  template <typename U,
287  typename cuda::std::enable_if_t<cuda::std::is_floating_point<U>::value>* = nullptr>
288  explicit constexpr operator U() const
289  {
290  return detail::shift<Rep, Rad>(static_cast<U>(_value), detail::negate(_scale));
291  }
292 
299  template <typename U,
300  typename cuda::std::enable_if_t<cuda::std::is_integral<U>::value>* = nullptr>
301  explicit constexpr operator U() const
302  {
303  // Don't cast to U until converting to Rep because in certain cases casting to U before shifting
304  // will result in integer overflow (i.e. if U = int32_t, Rep = int64_t and _value > 2 billion)
305  return static_cast<U>(detail::shift<Rep, Rad>(_value, detail::negate(_scale)));
306  }
307 
308  CUDA_HOST_DEVICE_CALLABLE operator scaled_integer<Rep>() const
309  {
310  return scaled_integer<Rep>{_value, _scale};
311  }
312 
318  CUDA_HOST_DEVICE_CALLABLE rep value() const { return _value; }
319 
325  CUDA_HOST_DEVICE_CALLABLE scale_type scale() const { return _scale; }
326 
332  CUDA_HOST_DEVICE_CALLABLE explicit constexpr operator bool() const
333  {
334  return static_cast<bool>(_value);
335  }
336 
344  template <typename Rep1, Radix Rad1>
345  CUDA_HOST_DEVICE_CALLABLE fixed_point<Rep1, Rad1>& operator+=(fixed_point<Rep1, Rad1> const& rhs)
346  {
347  *this = *this + rhs;
348  return *this;
349  }
350 
358  template <typename Rep1, Radix Rad1>
359  CUDA_HOST_DEVICE_CALLABLE fixed_point<Rep1, Rad1>& operator*=(fixed_point<Rep1, Rad1> const& rhs)
360  {
361  *this = *this * rhs;
362  return *this;
363  }
364 
372  template <typename Rep1, Radix Rad1>
373  CUDA_HOST_DEVICE_CALLABLE fixed_point<Rep1, Rad1>& operator-=(fixed_point<Rep1, Rad1> const& rhs)
374  {
375  *this = *this - rhs;
376  return *this;
377  }
378 
386  template <typename Rep1, Radix Rad1>
387  CUDA_HOST_DEVICE_CALLABLE fixed_point<Rep1, Rad1>& operator/=(fixed_point<Rep1, Rad1> const& rhs)
388  {
389  *this = *this / rhs;
390  return *this;
391  }
392 
398  CUDA_HOST_DEVICE_CALLABLE
400  {
401  *this = *this + fixed_point<Rep, Rad>{1, scale_type{_scale}};
402  return *this;
403  }
404 
416  template <typename Rep1, Radix Rad1>
417  CUDA_HOST_DEVICE_CALLABLE friend fixed_point<Rep1, Rad1> operator+(
418  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
419 
431  template <typename Rep1, Radix Rad1>
432  CUDA_HOST_DEVICE_CALLABLE friend fixed_point<Rep1, Rad1> operator-(
433  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
434 
444  template <typename Rep1, Radix Rad1>
445  CUDA_HOST_DEVICE_CALLABLE friend fixed_point<Rep1, Rad1> operator*(
446  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
447 
457  template <typename Rep1, Radix Rad1>
458  CUDA_HOST_DEVICE_CALLABLE friend fixed_point<Rep1, Rad1> operator/(
459  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
460 
472  template <typename Rep1, Radix Rad1>
473  CUDA_HOST_DEVICE_CALLABLE friend bool operator==(fixed_point<Rep1, Rad1> const& lhs,
474  fixed_point<Rep1, Rad1> const& rhs);
475 
487  template <typename Rep1, Radix Rad1>
488  CUDA_HOST_DEVICE_CALLABLE friend bool operator!=(fixed_point<Rep1, Rad1> const& lhs,
489  fixed_point<Rep1, Rad1> const& rhs);
490 
502  template <typename Rep1, Radix Rad1>
503  CUDA_HOST_DEVICE_CALLABLE friend bool operator<=(fixed_point<Rep1, Rad1> const& lhs,
504  fixed_point<Rep1, Rad1> const& rhs);
505 
517  template <typename Rep1, Radix Rad1>
518  CUDA_HOST_DEVICE_CALLABLE friend bool operator>=(fixed_point<Rep1, Rad1> const& lhs,
519  fixed_point<Rep1, Rad1> const& rhs);
520 
532  template <typename Rep1, Radix Rad1>
533  CUDA_HOST_DEVICE_CALLABLE friend bool operator<(fixed_point<Rep1, Rad1> const& lhs,
534  fixed_point<Rep1, Rad1> const& rhs);
535 
547  template <typename Rep1, Radix Rad1>
548  CUDA_HOST_DEVICE_CALLABLE friend bool operator>(fixed_point<Rep1, Rad1> const& lhs,
549  fixed_point<Rep1, Rad1> const& rhs);
550 
560  CUDA_HOST_DEVICE_CALLABLE fixed_point<Rep, Rad> rescaled(scale_type scale) const
561  {
562  if (scale == _scale) return *this;
563  Rep const value = detail::shift<Rep, Rad>(_value, scale_type{scale - _scale});
565  }
566 
570  explicit operator std::string() const
571  {
572  if (_scale < 0) {
573  auto const av = std::abs(_value);
574  int64_t const n = std::pow(10, -_scale);
575  int64_t const f = av % n;
576  auto const num_zeros =
577  std::max(0, (-_scale - static_cast<int32_t>(std::to_string(f).size())));
578  auto const zeros = std::string(num_zeros, '0');
579  auto const sign = _value < 0 ? std::string("-") : std::string();
580  return sign + std::to_string(av / n) + std::string(".") + zeros + std::to_string(av % n);
581  } else {
582  auto const zeros = std::string(_scale, '0');
583  return std::to_string(_value) + zeros;
584  }
585  }
586 };
587 
597 template <typename Rep, typename T>
598 CUDA_HOST_DEVICE_CALLABLE auto addition_overflow(T lhs, T rhs)
599 {
600  return rhs > 0 ? lhs > cuda::std::numeric_limits<Rep>::max() - rhs
601  : lhs < cuda::std::numeric_limits<Rep>::min() - rhs;
602 }
603 
612 template <typename Rep, typename T>
613 CUDA_HOST_DEVICE_CALLABLE auto subtraction_overflow(T lhs, T rhs)
614 {
615  return rhs > 0 ? lhs < cuda::std::numeric_limits<Rep>::min() + rhs
616  : lhs > cuda::std::numeric_limits<Rep>::max() + rhs;
617 }
618 
627 template <typename Rep, typename T>
628 CUDA_HOST_DEVICE_CALLABLE auto division_overflow(T lhs, T rhs)
629 {
630  return lhs == cuda::std::numeric_limits<Rep>::min() && rhs == -1;
631 }
632 
641 template <typename Rep, typename T>
642 CUDA_HOST_DEVICE_CALLABLE auto multiplication_overflow(T lhs, T rhs)
643 {
644  auto const min = cuda::std::numeric_limits<Rep>::min();
645  auto const max = cuda::std::numeric_limits<Rep>::max();
646  if (rhs > 0)
647  return lhs > max / rhs || lhs < min / rhs;
648  else if (rhs < -1)
649  return lhs > min / rhs || lhs < max / rhs;
650  else
651  return rhs == -1 && lhs == min;
652 }
653 
654 // PLUS Operation
655 template <typename Rep1, Radix Rad1>
656 CUDA_HOST_DEVICE_CALLABLE fixed_point<Rep1, Rad1> operator+(fixed_point<Rep1, Rad1> const& lhs,
657  fixed_point<Rep1, Rad1> const& rhs)
658 {
659  auto const scale = std::min(lhs._scale, rhs._scale);
660  auto const sum = lhs.rescaled(scale)._value + rhs.rescaled(scale)._value;
661 
662 #if defined(__CUDACC_DEBUG__)
663 
664  assert(!addition_overflow<Rep1>(lhs.rescaled(scale)._value, rhs.rescaled(scale)._value) &&
665  "fixed_point overflow");
666 
667 #endif
668 
669  return fixed_point<Rep1, Rad1>{scaled_integer<Rep1>{sum, scale}};
670 }
671 
672 // MINUS Operation
673 template <typename Rep1, Radix Rad1>
674 CUDA_HOST_DEVICE_CALLABLE fixed_point<Rep1, Rad1> operator-(fixed_point<Rep1, Rad1> const& lhs,
675  fixed_point<Rep1, Rad1> const& rhs)
676 {
677  auto const scale = std::min(lhs._scale, rhs._scale);
678  auto const diff = lhs.rescaled(scale)._value - rhs.rescaled(scale)._value;
679 
680 #if defined(__CUDACC_DEBUG__)
681 
682  assert(!subtraction_overflow<Rep1>(lhs.rescaled(scale)._value, rhs.rescaled(scale)._value) &&
683  "fixed_point overflow");
684 
685 #endif
686 
687  return fixed_point<Rep1, Rad1>{scaled_integer<Rep1>{diff, scale}};
688 }
689 
690 // MULTIPLIES Operation
691 template <typename Rep1, Radix Rad1>
692 CUDA_HOST_DEVICE_CALLABLE fixed_point<Rep1, Rad1> operator*(fixed_point<Rep1, Rad1> const& lhs,
693  fixed_point<Rep1, Rad1> const& rhs)
694 {
695 #if defined(__CUDACC_DEBUG__)
696 
697  assert(!multiplication_overflow<Rep1>(lhs._value, rhs._value) && "fixed_point overflow");
698 
699 #endif
700 
702  scaled_integer<Rep1>(lhs._value * rhs._value, scale_type{lhs._scale + rhs._scale})};
703 }
704 
705 // DIVISION Operation
706 template <typename Rep1, Radix Rad1>
707 CUDA_HOST_DEVICE_CALLABLE fixed_point<Rep1, Rad1> operator/(fixed_point<Rep1, Rad1> const& lhs,
708  fixed_point<Rep1, Rad1> const& rhs)
709 {
710 #if defined(__CUDACC_DEBUG__)
711 
712  assert(!division_overflow<Rep1>(lhs._value, rhs._value) && "fixed_point overflow");
713 
714 #endif
715 
717  scaled_integer<Rep1>(lhs._value / rhs._value, scale_type{lhs._scale - rhs._scale})};
718 }
719 
720 // EQUALITY COMPARISON Operation
721 template <typename Rep1, Radix Rad1>
722 CUDA_HOST_DEVICE_CALLABLE bool operator==(fixed_point<Rep1, Rad1> const& lhs,
723  fixed_point<Rep1, Rad1> const& rhs)
724 {
725  auto const scale = std::min(lhs._scale, rhs._scale);
726  return lhs.rescaled(scale)._value == rhs.rescaled(scale)._value;
727 }
728 
729 // EQUALITY NOT COMPARISON Operation
730 template <typename Rep1, Radix Rad1>
731 CUDA_HOST_DEVICE_CALLABLE bool operator!=(fixed_point<Rep1, Rad1> const& lhs,
732  fixed_point<Rep1, Rad1> const& rhs)
733 {
734  auto const scale = std::min(lhs._scale, rhs._scale);
735  return lhs.rescaled(scale)._value != rhs.rescaled(scale)._value;
736 }
737 
738 // LESS THAN OR EQUAL TO Operation
739 template <typename Rep1, Radix Rad1>
740 CUDA_HOST_DEVICE_CALLABLE bool operator<=(fixed_point<Rep1, Rad1> const& lhs,
741  fixed_point<Rep1, Rad1> const& rhs)
742 {
743  auto const scale = std::min(lhs._scale, rhs._scale);
744  return lhs.rescaled(scale)._value <= rhs.rescaled(scale)._value;
745 }
746 
747 // GREATER THAN OR EQUAL TO Operation
748 template <typename Rep1, Radix Rad1>
749 CUDA_HOST_DEVICE_CALLABLE bool operator>=(fixed_point<Rep1, Rad1> const& lhs,
750  fixed_point<Rep1, Rad1> const& rhs)
751 {
752  auto const scale = std::min(lhs._scale, rhs._scale);
753  return lhs.rescaled(scale)._value >= rhs.rescaled(scale)._value;
754 }
755 
756 // LESS THAN Operation
757 template <typename Rep1, Radix Rad1>
758 CUDA_HOST_DEVICE_CALLABLE bool operator<(fixed_point<Rep1, Rad1> const& lhs,
759  fixed_point<Rep1, Rad1> const& rhs)
760 {
761  auto const scale = std::min(lhs._scale, rhs._scale);
762  return lhs.rescaled(scale)._value < rhs.rescaled(scale)._value;
763 }
764 
765 // GREATER THAN Operation
766 template <typename Rep1, Radix Rad1>
767 CUDA_HOST_DEVICE_CALLABLE bool operator>(fixed_point<Rep1, Rad1> const& lhs,
768  fixed_point<Rep1, Rad1> const& rhs)
769 {
770  auto const scale = std::min(lhs._scale, rhs._scale);
771  return lhs.rescaled(scale)._value > rhs.rescaled(scale)._value;
772 }
773 
774 using decimal32 = fixed_point<int32_t, Radix::BASE_10>;
775 using decimal64 = fixed_point<int64_t, Radix::BASE_10>;
776  // end of group
778 } // namespace numeric
numeric::operator/
CUDA_HOST_DEVICE_CALLABLE fixed_point< Rep1, Rad1 > operator/(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:707
numeric::fixed_point::operator-
CUDA_HOST_DEVICE_CALLABLE 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:674
numeric::fixed_point::operator==
CUDA_HOST_DEVICE_CALLABLE 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:722
numeric::fixed_point::operator>
CUDA_HOST_DEVICE_CALLABLE 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:767
numeric::fixed_point::fixed_point
CUDA_HOST_DEVICE_CALLABLE fixed_point(scaled_integer< Rep > s)
Constructor that will not perform shifting (assumes value already shifted)
Definition: fixed_point.hpp:260
numeric::fixed_point::operator*=
CUDA_HOST_DEVICE_CALLABLE fixed_point< Rep1, Rad1 > & operator*=(fixed_point< Rep1, Rad1 > const &rhs)
operator *=
Definition: fixed_point.hpp:359
numeric::Radix
Radix
Scoped enumerator to use when constructing fixed_point
Definition: fixed_point.hpp:58
numeric::fixed_point
A type for representing a number with a fixed amount of precision.
Definition: fixed_point.hpp:213
types.hpp
Type declarations for libcudf.
numeric::fixed_point::scale
CUDA_HOST_DEVICE_CALLABLE scale_type scale() const
Method that returns the scale of the fixed_point number.
Definition: fixed_point.hpp:325
numeric::operator==
CUDA_HOST_DEVICE_CALLABLE bool operator==(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:722
numeric::subtraction_overflow
CUDA_HOST_DEVICE_CALLABLE auto subtraction_overflow(T lhs, T rhs)
Function for identifying integer overflow when subtracting.
Definition: fixed_point.hpp:613
numeric::fixed_point::value
CUDA_HOST_DEVICE_CALLABLE rep value() const
Method that returns the underlying value of the fixed_point number.
Definition: fixed_point.hpp:318
numeric::detail::ipow
CUDA_HOST_DEVICE_CALLABLE Rep ipow(T exponent)
A function for integer exponentiation by squaring.
Definition: fixed_point.hpp:92
numeric::detail::right_shift
constexpr CUDA_HOST_DEVICE_CALLABLE 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:129
numeric::operator!=
CUDA_HOST_DEVICE_CALLABLE bool operator!=(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:731
numeric::division_overflow
CUDA_HOST_DEVICE_CALLABLE auto division_overflow(T lhs, T rhs)
Function for identifying integer overflow when dividing.
Definition: fixed_point.hpp:628
numeric::fixed_point::operator+
CUDA_HOST_DEVICE_CALLABLE 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:656
numeric::detail::negate
CUDA_HOST_DEVICE_CALLABLE auto negate(scale_type const &scale)
Helper function to negate strongly typed scale_type.
Definition: fixed_point.hpp:115
numeric::operator>
CUDA_HOST_DEVICE_CALLABLE bool operator>(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:767
numeric::operator*
CUDA_HOST_DEVICE_CALLABLE fixed_point< Rep1, Rad1 > operator*(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:692
numeric::detail::left_shift
constexpr CUDA_HOST_DEVICE_CALLABLE 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:146
numeric::fixed_point::operator/
CUDA_HOST_DEVICE_CALLABLE 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:707
numeric::scaled_integer
Helper struct for constructing fixed_point when value is already shifted.
Definition: fixed_point.hpp:197
numeric::fixed_point::operator<
CUDA_HOST_DEVICE_CALLABLE 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:758
numeric::multiplication_overflow
CUDA_HOST_DEVICE_CALLABLE auto multiplication_overflow(T lhs, T rhs)
Function for identifying integer overflow when multiplying.
Definition: fixed_point.hpp:642
numeric::fixed_point::rescaled
CUDA_HOST_DEVICE_CALLABLE fixed_point< Rep, Rad > rescaled(scale_type scale) const
Method for creating a fixed_point number with a new scale
Definition: fixed_point.hpp:560
numeric::fixed_point::operator-=
CUDA_HOST_DEVICE_CALLABLE fixed_point< Rep1, Rad1 > & operator-=(fixed_point< Rep1, Rad1 > const &rhs)
operator -=
Definition: fixed_point.hpp:373
numeric::fixed_point::operator+=
CUDA_HOST_DEVICE_CALLABLE fixed_point< Rep1, Rad1 > & operator+=(fixed_point< Rep1, Rad1 > const &rhs)
operator +=
Definition: fixed_point.hpp:345
numeric::operator<
CUDA_HOST_DEVICE_CALLABLE bool operator<(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:758
numeric::fixed_point::operator++
CUDA_HOST_DEVICE_CALLABLE fixed_point< Rep, Rad > & operator++()
operator ++ (post-increment)
Definition: fixed_point.hpp:399
numeric::addition_overflow
CUDA_HOST_DEVICE_CALLABLE auto addition_overflow(T lhs, T rhs)
Function for identifying integer overflow when adding.
Definition: fixed_point.hpp:598
numeric::fixed_point::operator!=
CUDA_HOST_DEVICE_CALLABLE 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:731
numeric::operator<=
CUDA_HOST_DEVICE_CALLABLE bool operator<=(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:740
numeric::operator>=
CUDA_HOST_DEVICE_CALLABLE bool operator>=(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:749
numeric::fixed_point::operator/=
CUDA_HOST_DEVICE_CALLABLE fixed_point< Rep1, Rad1 > & operator/=(fixed_point< Rep1, Rad1 > const &rhs)
operator /=
Definition: fixed_point.hpp:387
numeric::operator+
CUDA_HOST_DEVICE_CALLABLE fixed_point< Rep1, Rad1 > operator+(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:656
numeric::fixed_point::operator*
CUDA_HOST_DEVICE_CALLABLE 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:692
numeric::fixed_point::operator>=
CUDA_HOST_DEVICE_CALLABLE 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:749
numeric::fixed_point::fixed_point
CUDA_HOST_DEVICE_CALLABLE fixed_point()
Default constructor that constructs fixed_point number with a value and scale of zero.
Definition: fixed_point.hpp:278
numeric::operator-
CUDA_HOST_DEVICE_CALLABLE fixed_point< Rep1, Rad1 > operator-(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
Definition: fixed_point.hpp:674
numeric
fixed_point and supporting types
Definition: fixed_point.hpp:33
numeric::fixed_point::operator<=
CUDA_HOST_DEVICE_CALLABLE 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:740