BAN: Use builtins for math overflow

This commit is contained in:
Bananymous 2026-04-02 14:49:12 +03:00
parent 21639071c2
commit 85f61aded5
1 changed files with 27 additions and 33 deletions

View File

@ -6,19 +6,6 @@
#include <float.h> #include <float.h>
// This is ugly but my clangd does not like including
// intrinsic headers at all
#if !defined(__SSE__) || !defined(__SSE2__)
#pragma GCC push_options
#ifndef __SSE__
#pragma GCC target("sse")
#endif
#ifndef __SSE2__
#pragma GCC target("sse2")
#endif
#define BAN_MATH_POP_OPTIONS
#endif
namespace BAN::Math namespace BAN::Math
{ {
@ -49,12 +36,11 @@ namespace BAN::Math
template<integral T> template<integral T>
inline constexpr T gcd(T a, T b) inline constexpr T gcd(T a, T b)
{ {
T t;
while (b) while (b)
{ {
t = b; T temp = b;
b = a % b; b = a % b;
a = t; a = temp;
} }
return a; return a;
} }
@ -79,25 +65,20 @@ namespace BAN::Math
return (x & (x - 1)) == 0; return (x & (x - 1)) == 0;
} }
template<BAN::integral T> template<integral T>
static constexpr bool will_multiplication_overflow(T a, T b) __attribute__((always_inline))
inline constexpr bool will_multiplication_overflow(T a, T b)
{ {
if (a == 0 || b == 0) T dummy;
return false; return __builtin_mul_overflow(a, b, &dummy);
if ((a > 0) == (b > 0))
return a > BAN::numeric_limits<T>::max() / b;
else
return a < BAN::numeric_limits<T>::min() / b;
} }
template<BAN::integral T> template<integral T>
static constexpr bool will_addition_overflow(T a, T b) __attribute__((always_inline))
inline constexpr bool will_addition_overflow(T a, T b)
{ {
if (a > 0 && b > 0) T dummy;
return a > BAN::numeric_limits<T>::max() - b; return __builtin_add_overflow(a, b, &dummy);
if (a < 0 && b < 0)
return a < BAN::numeric_limits<T>::min() - b;
return false;
} }
template<typename T> template<typename T>
@ -111,6 +92,19 @@ namespace BAN::Math
return sizeof(T) * 8 - __builtin_clzll(x) - 1; return sizeof(T) * 8 - __builtin_clzll(x) - 1;
} }
// This is ugly but my clangd does not like including
// intrinsic headers at all
#if !defined(__SSE__) || !defined(__SSE2__)
#pragma GCC push_options
#ifndef __SSE__
#pragma GCC target("sse")
#endif
#ifndef __SSE2__
#pragma GCC target("sse2")
#endif
#define BAN_MATH_POP_OPTIONS
#endif
template<floating_point T> template<floating_point T>
inline constexpr T floor(T x) inline constexpr T floor(T x)
{ {
@ -463,9 +457,9 @@ namespace BAN::Math
return sqrt<T>(x * x + y * y); return sqrt<T>(x * x + y * y);
} }
}
#ifdef BAN_MATH_POP_OPTIONS #ifdef BAN_MATH_POP_OPTIONS
#undef BAN_MATH_POP_OPTIONS #undef BAN_MATH_POP_OPTIONS
#pragma GCC pop_options #pragma GCC pop_options
#endif #endif
}