2025-08-05 13:53:59 +08:00
|
|
|
#pragma once
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
#include <concepts>
|
|
|
|
|
|
|
|
|
|
/**
|
2025-08-11 21:57:42 +08:00
|
|
|
* @brief The namespace providing functions for robust numeric operations.
|
2025-08-05 13:53:59 +08:00
|
|
|
* @details
|
2025-08-11 21:57:42 +08:00
|
|
|
* After writing some programs in Rust, I deeply appreciated the richness of operators
|
|
|
|
|
* for primitive types in Rust, which provides convenient operations like ceiling integral division.
|
|
|
|
|
* Therefore, I replicate these convenient features from Rust in this namespace.
|
2025-08-05 13:53:59 +08:00
|
|
|
*
|
2025-08-11 21:57:42 +08:00
|
|
|
* Currently unimplemented features due to lack of demand:
|
|
|
|
|
* \li Only supports unsigned integer ceiling division
|
2025-08-05 13:53:59 +08:00
|
|
|
*/
|
|
|
|
|
namespace yycc::num::op {
|
|
|
|
|
|
|
|
|
|
/**
|
2025-08-11 21:57:42 +08:00
|
|
|
* @brief Unsigned integer ceiling division
|
2025-08-05 13:53:59 +08:00
|
|
|
* @details
|
2025-08-11 21:57:42 +08:00
|
|
|
* Performs division between two unsigned integers and rounds up the result.
|
|
|
|
|
* @exception std::logic_error If the divisor is zero
|
|
|
|
|
* @tparam T The unsigned integer type for division operation
|
|
|
|
|
* @param[in] lhs Left operand
|
|
|
|
|
* @param[in] rhs Right operand
|
|
|
|
|
* @return Ceiling division result
|
2025-08-05 13:53:59 +08:00
|
|
|
*/
|
|
|
|
|
template<typename T>
|
|
|
|
|
requires std::unsigned_integral<T>
|
|
|
|
|
T div_ceil(T lhs, T rhs) {
|
2025-08-11 21:57:42 +08:00
|
|
|
// Check divisor first
|
2025-08-05 13:53:59 +08:00
|
|
|
if (rhs == 0) throw std::logic_error("div with 0");
|
2025-08-11 21:57:42 +08:00
|
|
|
// YYC MARK:
|
|
|
|
|
// We use this algorithm, instead of traditional `(lhs + rhs - 1) / rhs`,
|
|
|
|
|
// which may have unsafe overflow case.
|
2025-08-05 13:53:59 +08:00
|
|
|
return (lhs % rhs == 0) ? (lhs / rhs) : (lhs / rhs) + 1u;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|