cuda::sub_overflow#
Defined in <cuda/numeric> header.
namespace cuda {
template <class T>
struct overflow_result;
template <class Result = /*unspecified*/, class Lhs, class Rhs>
[[nodiscard]] __host__ __device__ constexpr
overflow_result</*see-below*/> sub_overflow(Lhs lhs, Rhs rhs) noexcept; // (1)
template <class Result, class Lhs, class Rhs>
[[nodiscard]] __host__ __device__ constexpr
bool sub_overflow(Result& result, Lhs lhs, Rhs rhs) noexcept; // (2)
} // namespace cuda
The function cuda::sub_overflow performs subtraction of two values lhs and rhs with overflow detection. The result is the same as if the operands were first promoted to an infinite precision signed type, subtracted, and then the result truncated to the type of the return value.
Parameters
result: The result of the subtraction (2).lhs: The left-hand side operand (1, 2).rhs: The right-hand side operand (1, 2).
Return value
Returns an overflow_result object containing the computed difference and a boolean flag indicating whether an overflow or underflow occurred. If the
Resulttype is specified, it will be used as the type of the result, otherwise the common type ofLhsandRhsis used.Returns
trueif an overflow or underflow occurred,falseotherwise.
Constraints
Result,Lhs, andRhsmust be integer types.
Performance considerations
No overflow checking is required when
lhs - rhsis always representable with theResulttype.Computation is generally faster when
Lhs,Rhs, andResulthave the same signedness.Unsigned computations are generally faster than signed computations.
The function uses PTX
asmon device and compiler intrinsics on host whenever possible.
Example#
#include <cuda/numeric>
#include <cuda/std/cassert>
#include <cuda/std/limits>
__global__ void kernel()
{
constexpr auto int_max = cuda::std::numeric_limits<int>::max();
constexpr auto int_min = cuda::std::numeric_limits<int>::min();
// cuda::sub_overflow(lhs, rhs) returning the common type of lhs and rhs
auto result = cuda::sub_overflow(3, 1))
assert(result.value == 2);
// cuda::sub_overflow<Result>(lhs, rhs) with an explicit result type
auto result2 = cuda::sub_overflow<long long>(int_min, 1);
assert(!result2.overflow);
assert(result2.value == static_cast<long long>(int_min) - 1ll);
unsigned result3{};
// cuda::sub_overflow(result, lhs, rhs) returning a bool flag
if (!cuda::sub_overflow(result, 5u, 3u))
{
assert(result == 2u);
}
}
int main()
{
kernel<<<1, 1>>>();
cudaDeviceSynchronize();
}