8 #include <cudf/detail/utilities/assert.cuh>
9 #include <cudf/fixed_point/temporary.hpp>
12 #include <cuda/numeric>
13 #include <cuda/std/cassert>
14 #include <cuda/std/cmath>
15 #include <cuda/std/functional>
16 #include <cuda/std/limits>
17 #include <cuda/std/type_traits>
18 #include <cuda/std/utility>
20 #ifndef __CUDACC_RTC__
49 enum class Radix : int32_t { BASE_2 = 2, BASE_10 = 10 };
60 return cuda::std::is_same_v<T, int32_t> ||
61 cuda::std::is_same_v<T, int64_t> ||
62 cuda::std::is_same_v<T, __int128_t>;
78 template <
typename Rep,
81 typename cuda::std::enable_if_t<(cuda::std::is_same_v<int32_t, T> &&
82 cuda::std::is_integral_v<Rep>)>* =
nullptr>
85 cudf_assert(exponent >= 0 &&
"integer exponentiation with negative exponent is not possible.");
87 if constexpr (Base == numeric::Radix::BASE_2) {
return static_cast<Rep
>(1) << exponent; }
93 if (exponent == 0) {
return static_cast<Rep
>(1); }
94 auto extra =
static_cast<Rep
>(1);
95 auto square =
static_cast<Rep
>(Base);
96 while (exponent > 1) {
97 if (exponent & 1) { extra *= square; }
101 return square * extra;
115 template <
typename Rep, Radix Rad,
typename T>
118 return val / ipow<Rep, Rad>(
static_cast<int32_t
>(scale));
132 template <
typename Rep, Radix Rad,
typename T>
135 return val * ipow<Rep, Rad>(
static_cast<int32_t
>(-scale));
151 template <
typename Rep, Radix Rad,
typename T>
154 if (scale == 0) {
return val; }
155 if (scale > 0) {
return right_shift<Rep, Rad>(val, scale); }
156 return left_shift<Rep, Rad>(val, scale);
177 template <
typename Rep,
178 typename cuda::std::enable_if_t<is_supported_representation_type<Rep>()>* =
nullptr>
200 template <
typename Rep, Radix Rad>
207 static constexpr
auto rad = Rad;
217 template <
typename T,
218 typename cuda::std::enable_if_t<cuda::std::is_integral_v<T> &&
219 is_supported_representation_type<Rep>()>* =
nullptr>
223 : _value{detail::shift<Rep, Rad>(static_cast<Rep>(value), scale)}, _scale{scale}
233 : _value{s.value}, _scale{s.scale}
244 template <
typename T,
typename cuda::std::enable_if_t<cuda::std::is_
integral_v<T>>* =
nullptr>
246 : _value{static_cast<Rep>(value)}, _scale{
scale_type{0}}
262 template <
typename U,
typename cuda::std::enable_if_t<cuda::std::is_
integral_v<U>>* =
nullptr>
268 auto const value = cuda::std::common_type_t<U, Rep>(_value);
269 return static_cast<U
>(detail::shift<Rep, Rad>(value,
scale_type{-_scale}));
303 return static_cast<bool>(_value);
314 template <
typename Rep1, Radix Rad1>
329 template <
typename Rep1, Radix Rad1>
344 template <
typename Rep1, Radix Rad1>
359 template <
typename Rep1, Radix Rad1>
390 template <
typename Rep1, Radix Rad1>
407 template <
typename Rep1, Radix Rad1>
422 template <
typename Rep1, Radix Rad1>
437 template <
typename Rep1, Radix Rad1>
454 template <
typename Rep1, Radix Rad1>
471 template <
typename Rep1, Radix Rad1>
488 template <
typename Rep1, Radix Rad1>
505 template <
typename Rep1, Radix Rad1>
522 template <
typename Rep1, Radix Rad1>
539 template <
typename Rep1, Radix Rad1>
556 template <
typename Rep1, Radix Rad1>
571 if (scale == _scale) {
return *
this; }
572 Rep
const value = detail::shift<Rep, Rad>(_value,
scale_type{scale - _scale});
576 #ifndef __CUDACC_RTC__
581 explicit operator std::string()
const
584 auto const av = detail::abs(_value);
585 Rep
const n = detail::exp10<Rep>(-_scale);
586 Rep
const f = av % n;
587 auto const num_zeros =
589 auto const zeros = std::string(num_zeros,
'0');
590 auto const sign = _value < 0 ? std::string(
"-") : std::string();
594 auto const zeros = std::string(_scale,
'0');
610 template <
typename Rep,
typename T>
613 return cuda::add_overflow<Rep>(lhs, rhs).overflow;
624 template <
typename Rep,
typename T>
627 return cuda::sub_overflow<Rep>(lhs, rhs).overflow;
638 template <
typename Rep,
typename T>
641 return cuda::div_overflow<Rep>(lhs, rhs).overflow;
652 template <
typename Rep,
typename T>
655 return cuda::mul_overflow<Rep>(lhs, rhs).overflow;
659 template <
typename Rep1, Radix Rad1>
663 auto const scale = cuda::std::min(lhs._scale, rhs._scale);
666 #if defined(__CUDACC_DEBUG__)
668 assert(!addition_overflow<Rep1>(lhs.
rescaled(scale)._value, rhs.
rescaled(scale)._value) &&
669 "fixed_point overflow");
677 template <
typename Rep1, Radix Rad1>
681 auto const scale = cuda::std::min(lhs._scale, rhs._scale);
684 #if defined(__CUDACC_DEBUG__)
686 assert(!subtraction_overflow<Rep1>(lhs.
rescaled(scale)._value, rhs.
rescaled(scale)._value) &&
687 "fixed_point overflow");
695 template <
typename Rep1, Radix Rad1>
699 #if defined(__CUDACC_DEBUG__)
701 assert(!multiplication_overflow<Rep1>(lhs._value, rhs._value) &&
"fixed_point overflow");
710 template <
typename Rep1, Radix Rad1>
714 #if defined(__CUDACC_DEBUG__)
716 assert(!division_overflow<Rep1>(lhs._value, rhs._value) &&
"fixed_point overflow");
725 template <
typename Rep1, Radix Rad1>
729 auto const scale = cuda::std::min(lhs._scale, rhs._scale);
734 template <
typename Rep1, Radix Rad1>
738 auto const scale = cuda::std::min(lhs._scale, rhs._scale);
743 template <
typename Rep1, Radix Rad1>
747 auto const scale = cuda::std::min(lhs._scale, rhs._scale);
752 template <
typename Rep1, Radix Rad1>
756 auto const scale = cuda::std::min(lhs._scale, rhs._scale);
761 template <
typename Rep1, Radix Rad1>
765 auto const scale = cuda::std::min(lhs._scale, rhs._scale);
770 template <
typename Rep1, Radix Rad1>
774 auto const scale = cuda::std::min(lhs._scale, rhs._scale);
779 template <
typename Rep1, Radix Rad1>
783 auto const scale = cuda::std::min(lhs._scale, rhs._scale);
784 auto const remainder = lhs.
rescaled(scale)._value % rhs.
rescaled(scale)._value;
788 template <
typename Rep>
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 rep value() const
Method that returns the underlying value of the fixed_point number.
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 fixed_point< Rep1, Rad1 > & operator+=(fixed_point< Rep1, Rad1 > const &rhs)
operator +=
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 fixed_point< Rep1, Rad1 > & operator/=(fixed_point< Rep1, Rad1 > const &rhs)
operator /=
CUDF_HOST_DEVICE fixed_point(T const &value, scale_type const &scale)
Constructor that will perform shifting to store value appropriately (from integral 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 Rep ipow(T exponent)
A function for integer exponentiation by squaring.
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
Radix
Scoped enumerator to use when constructing fixed_point
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)
scale_type
The scale type for fixed_point.
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.
constexpr CUDF_HOST_DEVICE auto is_supported_representation_type()
Returns true if the representation type is supported by fixed_point
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 char const * to_string(errc error)
Convert an errc error code to a human-readable string.
fixed_point and supporting types
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.