I would like to write a family of functions for various integer types INT, whose signature
INT safe_product(INT a, INT b, bool& error);
which takes two integers a and b and returns a * b if a * b does not overflow and returns 0 and sets the error to true if a * b overflows. I also want this feature to be effective, and I want it to run on 32-bit and 64-bit platforms.
I think overload safe_product using the std::int32_t, std::uint32_t, std::int64_t, std::uint64_tand etc. I believe that it is std::int64_tnot always defined with a 32-bit compiler. Is there a way to find out at compile time, if defined?
In addition, if we are on a 64-bit plate, the best way to implement a secure product between two 32-bit integers is:
std::int32_t safe_product(std::int32_t a, std::int32_t b,
bool& error) {
const std::int64_t a_64 = a;
const std::int64_t b_64 = b;
const std::int64_t ab_64 = a_64 * b_64;
if (ab_64 > std::numeric_limits<std::int32_t>::max() ||
ab_64 < std::numeric_limits<std::int32_t>::min()) {
error = true;
return 0;
} else {
error = false;
return static_cast<std::int32_t>(ab_64);
}
}
but if we are a 32-bit platform, the fastest algorithm may mean computing some integer division.
I have 2 questions:
How to declare mine safe_productso that it is defined for all integer types available on my platform (and obviously not for those that don't exist)?
How to make it efficient for both 32-bit and 64-bit using algorithms that I know?
source
share