/* Copyright (C) 2014-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk3mal.ctr */ /** @file dk3mal.c The dk3mal module. */ #line 306 "dk3mal.ctr" #include "dk3ma.h" #line 314 "dk3mal.ctr" long dk3ma_l_abs_ok(long a, int *ec) { if (NULL != ec) { if(DK3_L_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } } return ((0L <= a) ? a : (0L - a)); } long dk3ma_l_add_ok(long a, long b, int *ec) { if (NULL != ec) { if ((0L < a) && (0L < b)) { if((DK3_L_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; } } else { if ((0L > a) && (0L > b)) { if (DK3_L_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } else { if ((DK3_L_MIN - a) > b) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } } } return (a + b); } long dk3ma_l_sub_ok(long a, long b, int *ec) { if (NULL != ec) { if ((0L < a) && (0L > b)) { if((DK3_L_MAX + b) < a) { *ec = DK3_ERROR_MATH_OVERFLOW; } } else { if ((0L > a) && (0L < b)) { if((DK3_L_MIN + b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } } return (a - b); } #if VERSION_BEFORE_20141018 long dk3ma_l_mul_ok(long a, long b, int *ec) { if (NULL != ec) { if ((0L != a) && (0L != b)) { if ((DK3_L_MIN == a) && (1L != b)) { *ec = DK3_ERROR_MATH_OVERFLOW; goto checksfinished; } if ((DK3_L_MIN == b) && (1L != a)) { *ec = DK3_ERROR_MATH_OVERFLOW; goto checksfinished; } if ((DK3_L_MAX / dk3ma_l_abs_ok(a, ec)) < dk3ma_l_abs_ok(b, ec)) { *ec = DK3_ERROR_MATH_OVERFLOW; /* goto checksfinished; -- when adding further tests -- */ } } } checksfinished: return (a * b); } #else long dk3ma_l_mul_ok(long a, long b, int *ec) { if ((NULL != ec) && (0L != a) && (0L != b)) { if (DK3_L_MIN == a) { if (1L != b) { *ec = DK3_ERROR_MATH_OVERFLOW; } goto finished; } if (DK3_L_MIN == b) { if (1L != a) { *ec = DK3_ERROR_MATH_OVERFLOW; } goto finished; } if (0L < a) { if (0L < b) { if ((DK3_L_MAX / a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; } } else { if ((DK3_L_MIN / a) > b) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } else { if (0L < b) { if ((DK3_L_MIN / b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; } } else { if ((DK3_L_MAX / (0L - a)) < (0L - b)) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } } finished: return (a * b); } #endif long dk3ma_l_div_ok(long a, long b, int *ec) { long back = 0L; if (0L != b) { if ((DK3_L_MIN == a) && (-1L == b)) { back = DK3_L_MAX; *ec = DK3_ERROR_MATH_OVERFLOW; } else { back = a / b; } } else { if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; } if (0L <= a) { back = DK3_L_MAX; } else { back = DK3_L_MIN; } } return back; } long dk3ma_l_gcd_ok(long a, long b, int *ec) { long h; if (0L > a) { if (DK3_L_MIN == a) { a = 0L; if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; } goto finished; } else { a = 0L - a; } } if (0L > b) { if (DK3_L_MIN == b) { a = 0L; if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; } goto finished; } else { b = 0L - b; } } while (0L < b) { h = a % b; a = b; b = h; } if (0L == a) { a = 1L; } finished: return a; } #if DK3_HAVE_LONG_LONG long long dk3ma_ll_abs_ok(long long a, int *ec) { if (NULL != ec) { if(DK3_LL_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } } return ((0LL <= a) ? a : (0L - a)); } long long dk3ma_ll_add_ok(long long a, long long b, int *ec) { if (NULL != ec) { if ((0LL < a) && (0LL < b)) { if((DK3_LL_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; } } else { if ((0LL > a) && (0LL > b)) { if (DK3_LL_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } else { if ((DK3_LL_MIN - a) > b) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } } } return (a + b); } long long dk3ma_ll_sub_ok(long long a, long long b, int *ec) { if (NULL != ec) { if ((0LL < a) && (0LL > b)) { if((DK3_LL_MAX + b) < a) { *ec = DK3_ERROR_MATH_OVERFLOW; } } else { if ((0LL > a) && (0LL < b)) { if((DK3_LL_MIN + b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } } return (a - b); } #if VERSION_BEFORE_20141018 long long dk3ma_ll_mul_ok(long long a, long long b, int *ec) { if (NULL != ec) { if ((0LL != a) && (0LL != b)) { if ((DK3_LL_MIN == a) && (1LL != b)) { *ec = DK3_ERROR_MATH_OVERFLOW; goto checksfinished; } if ((DK3_LL_MIN == b) && (1LL != a)) { *ec = DK3_ERROR_MATH_OVERFLOW; goto checksfinished; } if ((DK3_LL_MAX / dk3ma_ll_abs_ok(a, ec)) < dk3ma_ll_abs_ok(b, ec)) { *ec = DK3_ERROR_MATH_OVERFLOW; /* goto checksfinished; -- when adding further tests -- */ } } } checksfinished: return (a * b); } #else long long dk3ma_ll_mul_ok(long long a, long long b, int *ec) { if ((NULL != ec) && (0LL != a) && (0LL != b)) { if (DK3_LL_MIN == a) { if (1LL != b) { *ec = DK3_ERROR_MATH_OVERFLOW; } goto finished; } if (DK3_LL_MIN == b) { if (1LL != a) { *ec = DK3_ERROR_MATH_OVERFLOW; } goto finished; } if (0LL < a) { if (0LL < b) { if ((DK3_LL_MAX / a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; } } else { if ((DK3_LL_MIN / a) > b) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } else { if (0LL < b) { if ((DK3_LL_MIN / b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; } } else { if ((DK3_LL_MAX / (0LL - a)) < (0LL - b)) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } } finished: return (a * b); } #endif long long dk3ma_ll_div_ok(long long a, long long b, int *ec) { long long back = 0L; if (0LL != b) { if ((DK3_LL_MIN == a) && (-1LL == b)) { back = DK3_LL_MAX; *ec = DK3_ERROR_MATH_OVERFLOW; } else { back = a / b; } } else { if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; } if (0LL <= a) { back = DK3_LL_MAX; } else { back = DK3_LL_MIN; } } return back; } long long dk3ma_ll_gcd_ok(long long a, long long b, int *ec) { long long h; if (0LL > a) { if (DK3_LL_MIN == a) { a = 0LL; if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; } goto finished; } else { a = 0LL - a; } } if (0LL > b) { if (DK3_LL_MIN == b) { a = 0LL; if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; } goto finished; } else { b = 0LL - b; } } while (0LL < b) { h = a % b; a = b; b = h; } if (0LL == a) { a = 1LL; } finished: return a; } #endif #if DK3_HAVE_INTMAX_T intmax_t dk3ma_intmax_t_abs_ok(intmax_t a, int *ec) { if (ec) { if (DK3_INTMAX_T_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } } return ((DK3_INTMAX_T_0 <= a) ? a : (DK3_INTMAX_T_0 - a)); } intmax_t dk3ma_intmax_t_add_ok(intmax_t a, intmax_t b, int *ec) { if (NULL != ec) { if ((DK3_INTMAX_T_0 < a) && (DK3_INTMAX_T_0 < b)) { if ((DK3_INTMAX_T_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; } } else { if ((DK3_INTMAX_T_0 > a) && (DK3_INTMAX_T_0 > b)) { if (DK3_INTMAX_T_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } else { if ((DK3_INTMAX_T_MIN - a) > b) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } } } return (a + b); } intmax_t dk3ma_intmax_t_sub_ok(intmax_t a, intmax_t b, int *ec) { if (NULL != ec) { if((DK3_INTMAX_T_0 < a) && (DK3_INTMAX_T_0 > b)) { if((DK3_INTMAX_T_MAX + b) < a) { *ec = DK3_ERROR_MATH_OVERFLOW; } } else { if((DK3_INTMAX_T_0 > a) && (DK3_INTMAX_T_0 < b)) { if((DK3_INTMAX_T_MIN + b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } } return (a - b); } #if VERSION_BEFORE_20141018 intmax_t dk3ma_intmax_t_mul_ok(intmax_t a, intmax_t b, int *ec) { if (NULL != ec) { if ((DK3_INTMAX_T_0 != a) && (DK3_INTMAX_T_0 != b)) { if ((DK3_INTMAX_T_MIN == a) && (DK3_INTMAX_T_1 != b)) { *ec = DK3_ERROR_MATH_OVERFLOW; goto checksfinished; } if ((DK3_INTMAX_T_MIN == b) && (DK3_INTMAX_T_1 != a)) { *ec = DK3_ERROR_MATH_OVERFLOW; goto checksfinished; } if ( (DK3_INTMAX_T_MAX / dk3ma_intmax_t_abs_ok(a, ec)) < dk3ma_intmax_t_abs_ok(b, ec) ) { *ec = DK3_ERROR_MATH_OVERFLOW; /* goto checksfinished; -- when adding further tests -- */ } } } checksfinished: return (a * b); } #else intmax_t dk3ma_intmax_t_mul_ok(intmax_t a, intmax_t b, int *ec) { if ((NULL != ec) && (DK3_INTMAX_T_0 != a) && (DK3_INTMAX_T_0 != b)) { if (DK3_INTMAX_T_MIN == a) { if (DK3_INTMAX_T_1 != b) { *ec = DK3_ERROR_MATH_OVERFLOW; } goto finished; } if (DK3_INTMAX_T_MIN == b) { if (DK3_INTMAX_T_1 != a) { *ec = DK3_ERROR_MATH_OVERFLOW; } goto finished; } if (DK3_INTMAX_T_0 < a) { if (DK3_INTMAX_T_0 < b) { if ((DK3_INTMAX_T_MAX / a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; } } else { if ((DK3_INTMAX_T_MIN / a) > b) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } else { if (DK3_INTMAX_T_0 < b) { if ((DK3_INTMAX_T_MIN / b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; } } else { if ((DK3_INTMAX_T_MAX / (DK3_INTMAX_T_0 - a)) < (DK3_INTMAX_T_0 - b)) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } } finished: return (a * b); } #endif intmax_t dk3ma_intmax_t_div_ok(intmax_t a, intmax_t b, int *ec) { intmax_t back = DK3_INTMAX_T_0; if (DK3_INTMAX_T_0 != b) { if ((DK3_INTMAX_T_MIN == a) && ((-DK3_INTMAX_T_1) == b)) { back = DK3_INTMAX_T_MAX; *ec = DK3_ERROR_MATH_OVERFLOW; } else { back = (a / b); } } else { if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; } if (DK3_INTMAX_T_0 <= a) { back = DK3_INTMAX_T_MAX; } else { back = DK3_INTMAX_T_MIN; } } return back; } intmax_t dk3ma_intmax_t_gcd_ok(intmax_t a, intmax_t b, int *ec) { intmax_t h; if (DK3_INTMAX_T_0 > a) { if (DK3_INTMAX_T_MIN == a) { a = DK3_INTMAX_T_0; if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; } goto finished; } else { a = DK3_INTMAX_T_0 - a; } } if (DK3_INTMAX_T_0 > b) { if (DK3_INTMAX_T_MIN == b) { a = DK3_INTMAX_T_0; if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; } goto finished; } else { b = DK3_INTMAX_T_0 - b; } } while (DK3_INTMAX_T_0 < b) { h = a % b; a = b; b = h; } if (DK3_INTMAX_T_0 == a) { a = DK3_INTMAX_T_1 ; } finished: return a; } #endif dk3_im_t dk3ma_im_abs_ok(dk3_im_t a, int *ec) { #if DK3_HAVE_INTMAX_T return (dk3ma_intmax_t_abs_ok(a, ec)); #else #if DK3_HAVE_LONG_LONG return (dk3ma_ll_abs_ok(a, ec)); #else return (dk3ma_l_abs_ok(a, ec)); #endif #endif } dk3_im_t dk3ma_im_add_ok(dk3_im_t a, dk3_im_t b, int *ec) { #if DK3_HAVE_INTMAX_T return (dk3ma_intmax_t_add_ok(a, b, ec)); #else #if DK3_HAVE_LONG_LONG return (dk3ma_ll_add_ok(a, b, ec)); #else return (dk3ma_l_add_ok(a, b, ec)); #endif #endif } dk3_im_t dk3ma_im_sub_ok(dk3_im_t a, dk3_im_t b, int *ec) { #if DK3_HAVE_INTMAX_T return (dk3ma_intmax_t_sub_ok(a, b, ec)); #else #if DK3_HAVE_LONG_LONG return (dk3ma_ll_sub_ok(a, b, ec)); #else return (dk3ma_l_sub_ok(a, b, ec)); #endif #endif } dk3_im_t dk3ma_im_mul_ok(dk3_im_t a, dk3_im_t b, int *ec) { #if DK3_HAVE_INTMAX_T return (dk3ma_intmax_t_mul_ok(a, b, ec)); #else #if DK3_HAVE_LONG_LONG return (dk3ma_ll_mul_ok(a, b, ec)); #else return (dk3ma_l_mul_ok(a, b, ec)); #endif #endif } dk3_im_t dk3ma_im_div_ok(dk3_im_t a, dk3_im_t b, int *ec) { #if DK3_HAVE_INTMAX_T return (dk3ma_intmax_t_div_ok(a, b, ec)); #else #if DK3_HAVE_LONG_LONG return (dk3ma_ll_div_ok(a, b, ec)); #else return (dk3ma_l_div_ok(a, b, ec)); #endif #endif } dk3_im_t dk3ma_im_gcd_ok(dk3_im_t a, dk3_im_t b, int *ec) { #if DK3_HAVE_INTMAX_T return (dk3ma_intmax_t_gcd_ok(a, b, ec)); #else #if DK3_HAVE_LONG_LONG return (dk3ma_ll_gcd_ok(a, b, ec)); #else return (dk3ma_l_gcd_ok(a, b, ec)); #endif #endif }