mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 13:31:27 +12:00
Implement rounded_div
Round-to-nearest integral based division, optimized for unsigned integral. Used in sceNpTrophyGetGameProgress. Do not allow signed values for aligned_div(), align().
This commit is contained in:
parent
e30173a835
commit
db4041e079
6 changed files with 31 additions and 16 deletions
|
@ -440,10 +440,29 @@ union alignas(2) f16
|
|||
|
||||
CHECK_SIZE_ALIGN(f16, 2, 2);
|
||||
|
||||
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
|
||||
constexpr T align(const T& value, ullong align)
|
||||
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value>>
|
||||
constexpr T align(T value, ullong align)
|
||||
{
|
||||
return static_cast<T>((value + (align - 1)) & ~(align - 1));
|
||||
return static_cast<T>((value + (align - 1)) & (0 - align));
|
||||
}
|
||||
|
||||
// General purpose aligned division, the result is rounded up not truncated
|
||||
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value>>
|
||||
constexpr T aligned_div(T value, ullong align)
|
||||
{
|
||||
return static_cast<T>((value + align - 1) / align);
|
||||
}
|
||||
|
||||
// General purpose aligned division, the result is rounded to nearest
|
||||
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
|
||||
constexpr T rounded_div(T value, std::conditional_t<std::is_signed<T>::value, llong, ullong> align)
|
||||
{
|
||||
if constexpr (std::is_unsigned<T>::value)
|
||||
{
|
||||
return static_cast<T>((value + (align / 2)) / align);
|
||||
}
|
||||
|
||||
return static_cast<T>((value + (value < 0 ? 0 - align : align) / 2) / align);
|
||||
}
|
||||
|
||||
template <typename T, typename T2>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue