/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* ft_safe_long_math.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: thrieg +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/11/08 11:11:17 by alier #+# #+# */ /* Updated: 2025/02/16 19:04:26 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. */ long safe_long_add(long a, long b) { if (b >= 0 && a > LONG_MAX - b) { errno = ERANGE; return (LONG_MAX); } else if (b < 0 && a < LONG_MIN - b) { errno = ERANGE; return (LONG_MIN); } return (a + b); } /* * Does saturate and never overflows/underflows. * Sets `errno` to `ERANGE` if the operation would * have caused an overflow/underflow. */ long safe_long_sub(long a, long b) { if (b >= 0 && a < LONG_MIN + b) { errno = ERANGE; return (LONG_MIN); } else if (b < 0 && a > LONG_MAX + b) { errno = ERANGE; return (LONG_MAX); } return (a - b); } /* * Does saturate and never overflows/underflows. * Sets `errno` to `ERANGE` if the operation would * have caused an overflow/underflow. */ long safe_long_mul(long a, long b) { if (b > 0) { if (a > 0 && a > LONG_MAX / b) return (errno = ERANGE, LONG_MAX); else if (a < 0 && a < LONG_MIN / b) return (errno = ERANGE, LONG_MIN); } else if (b < 0) { if (a < 0 && a < LONG_MAX / b) return (errno = ERANGE, LONG_MAX); else if ((-LONG_MAX > LONG_MIN && b < -1) && a > LONG_MIN / b) return (errno = ERANGE, LONG_MIN); } return (a * b); }