From 05e9d76c772881f5691874c3e11f0a9714bcd166 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 14 Jun 2024 11:04:29 +0300 Subject: [PATCH] BAN: Implement will_{addition,multiplication}_overflow --- BAN/include/BAN/Math.h | 22 ++++++++++++++++++++++ libc/stdlib.cpp | 27 +++------------------------ 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/BAN/include/BAN/Math.h b/BAN/include/BAN/Math.h index 617d330914..78a7794172 100644 --- a/BAN/include/BAN/Math.h +++ b/BAN/include/BAN/Math.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -65,6 +66,27 @@ namespace BAN::Math return (value & (value - 1)) == 0; } + template + static constexpr bool will_multiplication_overflow(T a, T b) + { + if (a == 0 || b == 0) + return false; + if ((a > 0) == (b > 0)) + return a > BAN::numeric_limits::max() / b; + else + return a < BAN::numeric_limits::min() / b; + } + + template + static constexpr bool will_addition_overflow(T a, T b) + { + if (a > 0 && b > 0) + return a > BAN::numeric_limits::max() - b; + if (a < 0 && b < 0) + return a < BAN::numeric_limits::min() - b; + return false; + } + template requires is_same_v || is_same_v || is_same_v inline constexpr T ilog2(T value) diff --git a/libc/stdlib.cpp b/libc/stdlib.cpp index 5fae412870..bdfe27a25e 100644 --- a/libc/stdlib.cpp +++ b/libc/stdlib.cpp @@ -64,35 +64,14 @@ static constexpr int get_base_digit(char c, int base) return -1; } -template -static constexpr bool will_multiplication_overflow(T a, T b) -{ - if (a == 0 || b == 0) - return false; - if ((a > 0) == (b > 0)) - return a > BAN::numeric_limits::max() / b; - else - return a < BAN::numeric_limits::min() / b; -} - -template -static constexpr bool will_addition_overflow(T a, T b) -{ - if (a > 0 && b > 0) - return a > BAN::numeric_limits::max() - b; - if (a < 0 && b < 0) - return a < BAN::numeric_limits::min() - b; - return false; -} - template static constexpr bool will_digit_append_overflow(bool negative, T current, int digit, int base) { if (BAN::is_unsigned_v && negative && digit) return true; - if (will_multiplication_overflow(current, base)) + if (BAN::Math::will_multiplication_overflow(current, base)) return true; - if (will_addition_overflow(current * base, current < 0 ? -digit : digit)) + if (BAN::Math::will_addition_overflow(current * base, current < 0 ? -digit : digit)) return true; return false; } @@ -286,7 +265,7 @@ static T strtoT(const char* str, char** endp, int& error) int extra_exponent = strtoT(str + 1, &maybe_end, 10, exp_error); if (exp_error != EINVAL) { - if (exp_error == ERANGE || will_addition_overflow(exponent, extra_exponent)) + if (exp_error == ERANGE || BAN::Math::will_addition_overflow(exponent, extra_exponent)) exponent = negative ? BAN::numeric_limits::min() : BAN::numeric_limits::max(); else exponent += extra_exponent;