diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk3mal.ctr |
Initial commit
Diffstat (limited to 'support/dktools/dk3mal.ctr')
-rw-r--r-- | support/dktools/dk3mal.ctr | 943 |
1 files changed, 943 insertions, 0 deletions
diff --git a/support/dktools/dk3mal.ctr b/support/dktools/dk3mal.ctr new file mode 100644 index 0000000000..730cbf7b4e --- /dev/null +++ b/support/dktools/dk3mal.ctr @@ -0,0 +1,943 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2014-xxxx +license = bsd + + + +%% header + +/** @file dk3mal.h Mathematical operations on long, long long, + intmax_t and dk3_im_t. +*/ + +#include <dk3conf.h> + +#include <stdio.h> +#if DK3_HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#if DK3_HAVE_STDINT +#include <stdint.h> +#endif +#if DK3_HAVE_INTTYPES_H +#include <inttypes.h> +#endif +#if DK3_HAVE_LIMITS_H +#include <limits.h> +#endif +#if DK3_HAVE_MATH_H +#include <math.h> +#endif +#if DK3_HAVE_FLOAT_H +#include <float.h> +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +/** Absolute value. + @param a Original value. + @param ec Pointer to error code variable, may be NULL. + @return Non-negative value on success, + DK3_L_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error. +*/ +long +dk3ma_l_abs_ok(long a, int *ec); + +/** Addition. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Summary of a and b. +*/ +long +dk3ma_l_add_ok(long a, long b, int *ec); + +/** Substraction. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Difference of a and b. +*/ +long +dk3ma_l_sub_ok(long a, long b, int *ec); + +/** Multiplication. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Product of a and b. +*/ +long +dk3ma_l_mul_ok(long a, long b, int *ec); + +/** Division. + @param a Left operand (nominator). + @param b Right operand (denominator). + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW or + DK3_ERROR_MATH_DIVZERO when returning. + @return Fraction of a and b. +*/ +long +dk3ma_l_div_ok(long a, long b, int *ec); + +/** Greatest common divisor. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Greatest common divisor of a and b on success, + 0L and ec = DK3_ERROR_MATH_OVERFLOW on error. +*/ +long +dk3ma_l_gcd_ok(long a, long b, int *ec); + + + +#if DK3_HAVE_LONG_LONG + +/** Absolute value. + @param a Original value. + @param ec Pointer to error code variable, may be NULL. + @return Non-negative value on success, + DK3_L_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error. +*/ +long long +dk3ma_ll_abs_ok(long long a, int *ec); + +/** Addition. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Summary of a and b. +*/ +long long +dk3ma_ll_add_ok(long long a, long long b, int *ec); + +/** Substraction. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Difference of a and b. +*/ +long long +dk3ma_ll_sub_ok(long long a, long long b, int *ec); + +/** Multiplication. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Product of a and b. +*/ +long long +dk3ma_ll_mul_ok(long long a, long long b, int *ec); + +/** Division. + @param a Left operand (nominator). + @param b Right operand (denominator). + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW or + DK3_ERROR_MATH_DIVZERO when returning. + @return Fraction of a and b. +*/ +long long +dk3ma_ll_div_ok(long long a, long long b, int *ec); + +/** Greatest common divisor. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Greatest common divisor of a and b on success, + 0L and ec = DK3_ERROR_MATH_OVERFLOW on error. +*/ +long long +dk3ma_ll_gcd_ok(long long a, long long b, int *ec); + +#endif +/* if DK3_HAVE_LONG_LONG */ + + + +#if DK3_HAVE_INTMAX_T + +/** Absolute value. + @param a Original value. + @param ec Pointer to error code variable, may be NULL. + @return Non-negative value on success, + DK3_L_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error. +*/ +intmax_t +dk3ma_intmax_t_abs_ok(intmax_t a, int *ec); + +/** Addition. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Summary of a and b. +*/ +intmax_t +dk3ma_intmax_t_add_ok(intmax_t a, intmax_t b, int *ec); + +/** Substraction. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Difference of a and b. +*/ +intmax_t +dk3ma_intmax_t_sub_ok(intmax_t a, intmax_t b, int *ec); + +/** Multiplication. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Product of a and b. +*/ +intmax_t +dk3ma_intmax_t_mul_ok(intmax_t a, intmax_t b, int *ec); + +/** Division. + @param a Left operand (nominator). + @param b Right operand (denominator). + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW or + DK3_ERROR_MATH_DIVZERO when returning. + @return Fraction of a and b. +*/ +intmax_t +dk3ma_intmax_t_div_ok(intmax_t a, intmax_t b, int *ec); + +/** Greatest common divisor. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Greatest common divisor of a and b on success, + 0L and ec = DK3_ERROR_MATH_OVERFLOW on error. +*/ +intmax_t +dk3ma_intmax_t_gcd_ok(intmax_t a, intmax_t b, int *ec); + +#endif + +/** Absolute value. + @param a Original value. + @param ec Pointer to error code variable, may be NULL. + @return Non-negative value on success, + DK3_L_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error. +*/ +dk3_im_t +dk3ma_im_abs_ok(dk3_im_t a, int *ec); + +/** Addition. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Summary of a and b. +*/ +dk3_im_t +dk3ma_im_add_ok(dk3_im_t a, dk3_im_t b, int *ec); + +/** Substraction. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Difference of a and b. +*/ +dk3_im_t +dk3ma_im_sub_ok(dk3_im_t a, dk3_im_t b, int *ec); + +/** Multiplication. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Product of a and b. +*/ +dk3_im_t +dk3ma_im_mul_ok(dk3_im_t a, dk3_im_t b, int *ec); + +/** Division. + @param a Left operand (nominator). + @param b Right operand (denominator). + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW or + DK3_ERROR_MATH_DIVZERO when returning. + @return Fraction of a and b. +*/ +dk3_im_t +dk3ma_im_div_ok(dk3_im_t a, dk3_im_t b, int *ec); + +/** Greatest common divisor. + @param a Left operand. + @param b Right operand. + @param ec Pointer to error code variable, may be NULL. + The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning. + @return Greatest common divisor of a and b on success, + 0L and ec = DK3_ERROR_MATH_OVERFLOW on error. +*/ +dk3_im_t +dk3ma_im_gcd_ok(dk3_im_t a, dk3_im_t b, int *ec); + +#ifdef __cplusplus +} +#endif + + + +%% module + + + +#include "dk3ma.h" + + + +$!trace-include + + + +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 +} + + |