/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* ft_safe_int_math.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: thrieg +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/11/08 11:11:17 by alier #+# #+# */ /* Updated: 2025/02/16 19:04:25 by thrieg ### ########.fr */ /* */ /* ************************************************************************** */ #include #include #include #include /* * Does saturate and never overflows/underflows. * Sets `errno` to `ERANGE` if the operation would * have caused an overflow/underflow. */ int safe_int_add(int a, int b) { if (b >= 0 && a > INT_MAX - b) { errno = ERANGE; return (INT_MAX); } else if (b < 0 && a < INT_MIN - b) { errno = ERANGE; return (INT_MIN); } return (a + b); } /* * Does saturate and never overflows/underflows. * Sets `errno` to `ERANGE` if the operation would * have caused an overflow/underflow. */ int safe_int_sub(int a, int b) { if (b >= 0 && a < INT_MIN + b) { errno = ERANGE; return (INT_MIN); } else if (b < 0 && a > INT_MAX + b) { errno = ERANGE; return (INT_MAX); } return (a - b); } /* * Does saturate and never overflows/underflows. * Sets `errno` to `ERANGE` if the operation would * have caused an overflow/underflow. */ int safe_int_mul(int a, int b) { if (b > 0) { if (a > 0 && a > INT_MAX / b) return (errno = ERANGE, INT_MAX); else if (a < 0 && a < INT_MIN / b) return (errno = ERANGE, INT_MIN); } else if (b < 0) { if (a < 0 && a < INT_MAX / b) return (errno = ERANGE, INT_MAX); else if ((-INT_MAX > INT_MIN && b < -1) && a > INT_MIN / b) return (errno = ERANGE, INT_MIN); } return (a * b); }