fixed_point.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020-2024, 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 #include <cuda/std/limits>
24 #include <cuda/std/type_traits>
25 #include <cuda/std/utility>
26 
27 #include <algorithm>
28 #include <cassert>
29 #include <cmath>
30 #include <string>
31 
33 namespace numeric {
34 
43 enum scale_type : int32_t {};
44 
54 enum class Radix : int32_t { BASE_2 = 2, BASE_10 = 10 };
55 
62 template <typename T>
63 constexpr inline auto is_supported_representation_type()
64 {
65  return cuda::std::is_same_v<T, int32_t> || //
66  cuda::std::is_same_v<T, int64_t> || //
67  cuda::std::is_same_v<T, __int128_t>;
68 }
69 
76 template <typename T>
77 constexpr inline auto is_supported_construction_value_type()
78 {
79  return cuda::std::is_integral<T>() || cuda::std::is_floating_point_v<T>;
80 }
81  // end of group
83 
84 // Helper functions for `fixed_point` type
85 namespace detail {
86 
95 template <typename Rep,
96  Radix Base,
97  typename T,
98  typename cuda::std::enable_if_t<(cuda::std::is_same_v<int32_t, T> &&
99  is_supported_representation_type<Rep>())>* = nullptr>
100 CUDF_HOST_DEVICE inline Rep ipow(T exponent)
101 {
102  cudf_assert(exponent >= 0 && "integer exponentiation with negative exponent is not possible.");
103 
104  if constexpr (Base == numeric::Radix::BASE_2) { return static_cast<Rep>(1) << exponent; }
105 
106  // Note: Including an array here introduces too much register pressure
107  // https://simple.wikipedia.org/wiki/Exponentiation_by_squaring
108  // This is the iterative equivalent of the recursive definition (faster)
109  // Quick-bench for squaring: http://quick-bench.com/Wg7o7HYQC9FW5M0CO0wQAjSwP_Y
110  if (exponent == 0) { return static_cast<Rep>(1); }
111  auto extra = static_cast<Rep>(1);
112  auto square = static_cast<Rep>(Base);
113  while (exponent > 1) {
114  if (exponent & 1) { extra *= square; }
115  exponent >>= 1;
116  square *= square;
117  }
118  return square * extra;
119 }
120 
132 template <typename Rep, Radix Rad, typename T>
133 CUDF_HOST_DEVICE inline constexpr T right_shift(T const& val, scale_type const& scale)
134 {
135  return val / ipow<Rep, Rad>(static_cast<int32_t>(scale));
136 }
137 
149 template <typename Rep, Radix Rad, typename T>
150 CUDF_HOST_DEVICE inline constexpr T left_shift(T const& val, scale_type const& scale)
151 {
152  return val * ipow<Rep, Rad>(static_cast<int32_t>(-scale));
153 }
154 
168 template <typename Rep, Radix Rad, typename T>
169 CUDF_HOST_DEVICE inline constexpr T shift(T const& val, scale_type const& scale)
170 {
171  if (scale == 0) { return val; }
172  if (scale > 0) { return right_shift<Rep, Rad>(val, scale); }
173  return left_shift<Rep, Rad>(val, scale);
174 }
175 
176 } // namespace detail
177 
196 template <typename Rep,
197  typename cuda::std::enable_if_t<is_supported_representation_type<Rep>()>* = nullptr>
199  Rep value;
207  CUDF_HOST_DEVICE inline explicit scaled_integer(Rep v, scale_type s) : value{v}, scale{s} {}
208 };
209 
219 template <typename Rep, Radix Rad>
220 class fixed_point {
221  Rep _value{};
222  scale_type _scale;
223 
224  public:
225  using rep = Rep;
226 
235  template <typename T,
236  typename cuda::std::enable_if_t<cuda::std::is_floating_point<T>() &&
237  is_supported_representation_type<Rep>()>* = nullptr>
238  CUDF_HOST_DEVICE inline explicit fixed_point(T const& value, scale_type const& scale)
239  : _value{static_cast<Rep>(detail::shift<Rep, Rad>(value, scale))}, _scale{scale}
240  {
241  }
242 
251  template <typename T,
252  typename cuda::std::enable_if_t<cuda::std::is_integral<T>() &&
253  is_supported_representation_type<Rep>()>* = nullptr>
254  CUDF_HOST_DEVICE inline explicit fixed_point(T const& value, scale_type const& scale)
255  // `value` is cast to `Rep` to avoid overflow in cases where
256  // constructing to `Rep` that is wider than `T`
257  : _value{detail::shift<Rep, Rad>(static_cast<Rep>(value), scale)}, _scale{scale}
258  {
259  }
260 
267  : _value{s.value}, _scale{s.scale}
268  {
269  }
270 
278  template <typename T,
279  typename cuda::std::enable_if_t<is_supported_construction_value_type<T>()>* = nullptr>
281  : _value{static_cast<Rep>(value)}, _scale{scale_type{0}}
282  {
283  }
284 
289  CUDF_HOST_DEVICE inline fixed_point() : _scale{scale_type{0}} {}
290 
297  template <typename U,
298  typename cuda::std::enable_if_t<cuda::std::is_floating_point_v<U>>* = nullptr>
299  explicit constexpr operator U() const
300  {
301  return detail::shift<Rep, Rad>(static_cast<U>(_value), scale_type{-_scale});
302  }
303 
310  template <typename U, typename cuda::std::enable_if_t<cuda::std::is_integral_v<U>>* = nullptr>
311  explicit constexpr operator U() const
312  {
313  // Cast to the larger of the two types (of U and Rep) before converting to Rep because in
314  // certain cases casting to U before shifting will result in integer overflow (i.e. if U =
315  // int32_t, Rep = int64_t and _value > 2 billion)
316  auto const value = std::common_type_t<U, Rep>(_value);
317  return static_cast<U>(detail::shift<Rep, Rad>(value, scale_type{-_scale}));
318  }
319 
325  CUDF_HOST_DEVICE inline operator scaled_integer<Rep>() const
326  {
327  return scaled_integer<Rep>{_value, _scale};
328  }
329 
335  CUDF_HOST_DEVICE inline rep value() const { return _value; }
336 
342  CUDF_HOST_DEVICE inline scale_type scale() const { return _scale; }
343 
349  CUDF_HOST_DEVICE inline explicit constexpr operator bool() const
350  {
351  return static_cast<bool>(_value);
352  }
353 
362  template <typename Rep1, Radix Rad1>
364  {
365  *this = *this + rhs;
366  return *this;
367  }
368 
377  template <typename Rep1, Radix Rad1>
379  {
380  *this = *this * rhs;
381  return *this;
382  }
383 
392  template <typename Rep1, Radix Rad1>
394  {
395  *this = *this - rhs;
396  return *this;
397  }
398 
407  template <typename Rep1, Radix Rad1>
409  {
410  *this = *this / rhs;
411  return *this;
412  }
413 
420  {
421  *this = *this + fixed_point<Rep, Rad>{1, scale_type{_scale}};
422  return *this;
423  }
424 
438  template <typename Rep1, Radix Rad1>
440  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
441 
455  template <typename Rep1, Radix Rad1>
457  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
458 
470  template <typename Rep1, Radix Rad1>
472  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
473 
485  template <typename Rep1, Radix Rad1>
487  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
488 
502  template <typename Rep1, Radix Rad1>
504  fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);
505 
519  template <typename Rep1, Radix Rad1>
520  CUDF_HOST_DEVICE inline friend bool operator==(fixed_point<Rep1, Rad1> const& lhs,
521  fixed_point<Rep1, Rad1> const& rhs);
522 
536  template <typename Rep1, Radix Rad1>
537  CUDF_HOST_DEVICE inline friend bool operator!=(fixed_point<Rep1, Rad1> const& lhs,
538  fixed_point<Rep1, Rad1> const& rhs);
539 
553  template <typename Rep1, Radix Rad1>
554  CUDF_HOST_DEVICE inline friend bool operator<=(fixed_point<Rep1, Rad1> const& lhs,
555  fixed_point<Rep1, Rad1> const& rhs);
556 
570  template <typename Rep1, Radix Rad1>
571  CUDF_HOST_DEVICE inline friend bool operator>=(fixed_point<Rep1, Rad1> const& lhs,
572  fixed_point<Rep1, Rad1> const& rhs);
573 
587  template <typename Rep1, Radix Rad1>
588  CUDF_HOST_DEVICE inline friend bool operator<(fixed_point<Rep1, Rad1> const& lhs,
589  fixed_point<Rep1, Rad1> const& rhs);
590 
604  template <typename Rep1, Radix Rad1>
605  CUDF_HOST_DEVICE inline friend bool operator>(fixed_point<Rep1, Rad1> const& lhs,
606  fixed_point<Rep1, Rad1> const& rhs);
607 
618  {
619  if (scale == _scale) { return *this; }
620  Rep const value = detail::shift<Rep, Rad>(_value, scale_type{scale - _scale});
622  }
623 
627  explicit operator std::string() const
628  {
629  if (_scale < 0) {
630  auto const av = detail::abs(_value);
631  Rep const n = detail::exp10<Rep>(-_scale);
632  Rep const f = av % n;
633  auto const num_zeros =
634  std::max(0, (-_scale - static_cast<int32_t>(detail::to_string(f).size())));
635  auto const zeros = std::string(num_zeros, '0');
636  auto const sign = _value < 0 ? std::string("-") : std::string();
637  return sign + detail::to_string(av / n) + std::string(".") + zeros +
638  detail::to_string(av % n);
639  }
640  auto const zeros = std::string(_scale, '0');
641  return detail::to_string(_value) + zeros;
642  }
643 };
644 
654 template <typename Rep, typename T>
655 CUDF_HOST_DEVICE inline auto addition_overflow(T lhs, T rhs)
656 {
657  return rhs > 0 ? lhs > cuda::std::numeric_limits<Rep>::max() - rhs
658  : lhs < cuda::std::numeric_limits<Rep>::min() - rhs;
659 }
660 
669 template <typename Rep, typename T>
670 CUDF_HOST_DEVICE inline auto subtraction_overflow(T lhs, T rhs)
671 {
672  return rhs > 0 ? lhs < cuda::std::numeric_limits<Rep>::min() + rhs
673  : lhs > cuda::std::numeric_limits<Rep>::max() + rhs;
674 }
675 
684 template <typename Rep, typename T>
685 CUDF_HOST_DEVICE inline auto division_overflow(T lhs, T rhs)
686 {
687  return lhs == cuda::std::numeric_limits<Rep>::min() && rhs == -1;
688 }
689 
698 template <typename Rep, typename T>
699 CUDF_HOST_DEVICE inline auto multiplication_overflow(T lhs, T rhs)
700 {
701  auto const min = cuda::std::numeric_limits<Rep>::min();
702  auto const max = cuda::std::numeric_limits<Rep>::max();
703  if (rhs > 0) { return lhs > max / rhs || lhs < min / rhs; }
704  if (rhs < -1) { return lhs > min / rhs || lhs < max / rhs; }
705  return rhs == -1 && lhs == min;
706 }
707 
708 // PLUS Operation
709 template <typename Rep1, Radix Rad1>
711  fixed_point<Rep1, Rad1> const& rhs)
712 {
713  auto const scale = std::min(lhs._scale, rhs._scale);
714  auto const sum = lhs.rescaled(scale)._value + rhs.rescaled(scale)._value;
715 
716 #if defined(__CUDACC_DEBUG__)
717 
718  assert(!addition_overflow<Rep1>(lhs.rescaled(scale)._value, rhs.rescaled(scale)._value) &&
719  "fixed_point overflow");
720 
721 #endif
722 
723  return fixed_point<Rep1, Rad1>{scaled_integer<Rep1>{sum, scale}};
724 }
725 
726 // MINUS Operation
727 template <typename Rep1, Radix Rad1>
729  fixed_point<Rep1, Rad1> const& rhs)
730 {
731  auto const scale = std::min(lhs._scale, rhs._scale);
732  auto const diff = lhs.rescaled(scale)._value - rhs.rescaled(scale)._value;
733 
734 #if defined(__CUDACC_DEBUG__)
735 
736  assert(!subtraction_overflow<Rep1>(lhs.rescaled(scale)._value, rhs.rescaled(scale)._value) &&
737  "fixed_point overflow");
738 
739 #endif
740 
741  return fixed_point<Rep1, Rad1>{scaled_integer<Rep1>{diff, scale}};
742 }
743 
744 // MULTIPLIES Operation
745 template <typename Rep1, Radix Rad1>
747  fixed_point<Rep1, Rad1> const& rhs)
748 {
749 #if defined(__CUDACC_DEBUG__)
750 
751  assert(!multiplication_overflow<Rep1>(lhs._value, rhs._value) && "fixed_point overflow");
752 
753 #endif
754 
756  scaled_integer<Rep1>(lhs._value * rhs._value, scale_type{lhs._scale + rhs._scale})};
757 }
758 
759 // DIVISION Operation
760 template <typename Rep1, Radix Rad1>
762  fixed_point<Rep1, Rad1> const& rhs)
763 {
764 #if defined(__CUDACC_DEBUG__)
765 
766  assert(!division_overflow<Rep1>(lhs._value, rhs._value) && "fixed_point overflow");
767 
768 #endif
769 
771  scaled_integer<Rep1>(lhs._value / rhs._value, scale_type{lhs._scale - rhs._scale})};
772 }
773 
774 // EQUALITY COMPARISON Operation
775 template <typename Rep1, Radix Rad1>
777  fixed_point<Rep1, Rad1> const& rhs)
778 {
779  auto const scale = std::min(lhs._scale, rhs._scale);
780  return lhs.rescaled(scale)._value == rhs.rescaled(scale)._value;
781 }
782 
783 // EQUALITY NOT COMPARISON Operation
784 template <typename Rep1, Radix Rad1>
786  fixed_point<Rep1, Rad1> const& rhs)
787 {
788  auto const scale = std::min(lhs._scale, rhs._scale);
789  return lhs.rescaled(scale)._value != rhs.rescaled(scale)._value;
790 }
791 
792 // LESS THAN OR EQUAL TO Operation
793 template <typename Rep1, Radix Rad1>
795  fixed_point<Rep1, Rad1> const& rhs)
796 {
797  auto const scale = std::min(lhs._scale, rhs._scale);
798  return lhs.rescaled(scale)._value <= rhs.rescaled(scale)._value;
799 }
800 
801 // GREATER THAN OR EQUAL TO Operation
802 template <typename Rep1, Radix Rad1>
804  fixed_point<Rep1, Rad1> const& rhs)
805 {
806  auto const scale = std::min(lhs._scale, rhs._scale);
807  return lhs.rescaled(scale)._value >= rhs.rescaled(scale)._value;
808 }
809 
810 // LESS THAN Operation
811 template <typename Rep1, Radix Rad1>
813  fixed_point<Rep1, Rad1> const& rhs)
814 {
815  auto const scale = std::min(lhs._scale, rhs._scale);
816  return lhs.rescaled(scale)._value < rhs.rescaled(scale)._value;
817 }
818 
819 // GREATER THAN Operation
820 template <typename Rep1, Radix Rad1>
822  fixed_point<Rep1, Rad1> const& rhs)
823 {
824  auto const scale = std::min(lhs._scale, rhs._scale);
825  return lhs.rescaled(scale)._value > rhs.rescaled(scale)._value;
826 }
827 
828 // MODULO OPERATION
829 template <typename Rep1, Radix Rad1>
831  fixed_point<Rep1, Rad1> const& rhs)
832 {
833  auto const scale = std::min(lhs._scale, rhs._scale);
834  auto const remainder = lhs.rescaled(scale)._value % rhs.rescaled(scale)._value;
835  return fixed_point<Rep1, Rad1>{scaled_integer<Rep1>{remainder, scale}};
836 }
837 
841  // end of group
843 } // namespace numeric
A type for representing a number with a fixed amount of precision.
CUDF_HOST_DEVICE fixed_point(scaled_integer< Rep > s)
Constructor that will not perform shifting (assumes value already shifted)
CUDF_HOST_DEVICE fixed_point< Rep, Rad > rescaled(scale_type scale) const
Method for creating a fixed_point number with a new scale
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)
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)
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)
CUDF_HOST_DEVICE rep value() const
Method that returns the underlying value of the fixed_point number.
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)
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > & operator*=(fixed_point< Rep1, Rad1 > const &rhs)
operator *=
CUDF_HOST_DEVICE scale_type scale() const
Method that returns the scale of the fixed_point number.
CUDF_HOST_DEVICE fixed_point(T const &value)
"Scale-less" constructor that constructs fixed_point number with a specified value and scale of zero
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > & operator-=(fixed_point< Rep1, Rad1 > const &rhs)
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)
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > & operator+=(fixed_point< Rep1, Rad1 > const &rhs)
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)
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)
Rep rep
The representation type.
CUDF_HOST_DEVICE fixed_point()
Default constructor that constructs fixed_point number with a value and scale of zero.
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)
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)
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > & operator/=(fixed_point< Rep1, Rad1 > const &rhs)
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)
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)
CUDF_HOST_DEVICE fixed_point(T const &value, scale_type const &scale)
Constructor that will perform shifting to store value appropriately (from floating point types)
CUDF_HOST_DEVICE fixed_point< Rep, Rad > & operator++()
operator ++ (post-increment)
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
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
CUDF_HOST_DEVICE Rep ipow(T exponent)
A function for integer exponentiation by squaring.
Radix
Scoped enumerator to use when constructing fixed_point
Definition: fixed_point.hpp:54
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > operator-(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
CUDF_HOST_DEVICE bool operator>=(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
CUDF_HOST_DEVICE bool operator<=(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
CUDF_HOST_DEVICE bool operator==(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > operator%(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
CUDF_HOST_DEVICE auto division_overflow(T lhs, T rhs)
Function for identifying integer overflow when dividing.
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > operator/(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
constexpr auto is_supported_construction_value_type()
Returns true if the value type is supported for constructing a fixed_point
Definition: fixed_point.hpp:77
scale_type
The scale type for fixed_point.
Definition: fixed_point.hpp:43
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > operator*(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
CUDF_HOST_DEVICE bool operator>(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
CUDF_HOST_DEVICE auto addition_overflow(T lhs, T rhs)
Function for identifying integer overflow when adding.
CUDF_HOST_DEVICE fixed_point< Rep1, Rad1 > operator+(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
CUDF_HOST_DEVICE auto multiplication_overflow(T lhs, T rhs)
Function for identifying integer overflow when multiplying.
CUDF_HOST_DEVICE bool operator!=(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
CUDF_HOST_DEVICE auto subtraction_overflow(T lhs, T rhs)
Function for identifying integer overflow when subtracting.
CUDF_HOST_DEVICE bool operator<(fixed_point< Rep1, Rad1 > const &lhs, fixed_point< Rep1, Rad1 > const &rhs)
constexpr auto is_supported_representation_type()
Returns true if the representation type is supported by fixed_point
Definition: fixed_point.hpp:63
fixed_point and supporting types
Definition: fixed_point.hpp:33
Helper struct for constructing fixed_point when value is already shifted.
Rep value
The value of the fixed point number.
CUDF_HOST_DEVICE scaled_integer(Rep v, scale_type s)
Constructor for scaled_integer
scale_type scale
The scale of the value.
Type declarations for libcudf.
#define CUDF_HOST_DEVICE
Indicates that the function or method is usable on host and device.
Definition: types.hpp:32