BAN: Implement will_{addition,multiplication}_overflow
This commit is contained in:
		
							parent
							
								
									ea7fc7f6c4
								
							
						
					
					
						commit
						05e9d76c77
					
				|  | @ -1,5 +1,6 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <BAN/Limits.h> | ||||
| #include <BAN/Traits.h> | ||||
| 
 | ||||
| #include <stddef.h> | ||||
|  | @ -65,6 +66,27 @@ namespace BAN::Math | |||
| 		return (value & (value - 1)) == 0; | ||||
| 	} | ||||
| 
 | ||||
| 	template<BAN::integral T> | ||||
| 	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<T>::max() / b; | ||||
| 		else | ||||
| 			return a < BAN::numeric_limits<T>::min() / b; | ||||
| 	} | ||||
| 
 | ||||
| 	template<BAN::integral T> | ||||
| 	static constexpr bool will_addition_overflow(T a, T b) | ||||
| 	{ | ||||
| 		if (a > 0 && b > 0) | ||||
| 			return a > BAN::numeric_limits<T>::max() - b; | ||||
| 		if (a < 0 && b < 0) | ||||
| 			return a < BAN::numeric_limits<T>::min() - b; | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	template<typename T> | ||||
| 	requires is_same_v<T, unsigned int> || is_same_v<T, unsigned long> || is_same_v<T, unsigned long long> | ||||
| 	inline constexpr T ilog2(T value) | ||||
|  |  | |||
|  | @ -64,35 +64,14 @@ static constexpr int get_base_digit(char c, int base) | |||
| 	return -1; | ||||
| } | ||||
| 
 | ||||
| template<BAN::integral T> | ||||
| 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<T>::max() / b; | ||||
| 	else | ||||
| 		return a < BAN::numeric_limits<T>::min() / b; | ||||
| } | ||||
| 
 | ||||
| template<BAN::integral T> | ||||
| static constexpr bool will_addition_overflow(T a, T b) | ||||
| { | ||||
| 	if (a > 0 && b > 0) | ||||
| 		return a > BAN::numeric_limits<T>::max() - b; | ||||
| 	if (a < 0 && b < 0) | ||||
| 		return a < BAN::numeric_limits<T>::min() - b; | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| template<BAN::integral T> | ||||
| static constexpr bool will_digit_append_overflow(bool negative, T current, int digit, int base) | ||||
| { | ||||
| 	if (BAN::is_unsigned_v<T> && negative && digit) | ||||
| 		return true; | ||||
| 	if (will_multiplication_overflow<T>(current, base)) | ||||
| 	if (BAN::Math::will_multiplication_overflow<T>(current, base)) | ||||
| 		return true; | ||||
| 	if (will_addition_overflow<T>(current * base, current < 0 ? -digit : digit)) | ||||
| 	if (BAN::Math::will_addition_overflow<T>(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<int>(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<int>::min() : BAN::numeric_limits<int>::max(); | ||||
| 			else | ||||
| 				exponent += extra_exponent; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue