📄 numeric.c
字号:
init_var(&arg1); init_var(&arg2); set_var_from_num(num1, &arg1); set_var_from_num(num2, &arg2); result = cmp_var(&arg1, &arg2); free_var(&arg1); free_var(&arg2); return (result == 0);}boolnumeric_ne(Numeric num1, Numeric num2){ int result; NumericVar arg1; NumericVar arg2; if (num1 == NULL || num2 == NULL) return FALSE; if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) return FALSE; init_var(&arg1); init_var(&arg2); set_var_from_num(num1, &arg1); set_var_from_num(num2, &arg2); result = cmp_var(&arg1, &arg2); free_var(&arg1); free_var(&arg2); return (result != 0);}boolnumeric_gt(Numeric num1, Numeric num2){ int result; NumericVar arg1; NumericVar arg2; if (num1 == NULL || num2 == NULL) return FALSE; if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) return FALSE; init_var(&arg1); init_var(&arg2); set_var_from_num(num1, &arg1); set_var_from_num(num2, &arg2); result = cmp_var(&arg1, &arg2); free_var(&arg1); free_var(&arg2); return (result > 0);}boolnumeric_ge(Numeric num1, Numeric num2){ int result; NumericVar arg1; NumericVar arg2; if (num1 == NULL || num2 == NULL) return FALSE; if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) return FALSE; init_var(&arg1); init_var(&arg2); set_var_from_num(num1, &arg1); set_var_from_num(num2, &arg2); result = cmp_var(&arg1, &arg2); free_var(&arg1); free_var(&arg2); return (result >= 0);}boolnumeric_lt(Numeric num1, Numeric num2){ int result; NumericVar arg1; NumericVar arg2; if (num1 == NULL || num2 == NULL) return FALSE; if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) return FALSE; init_var(&arg1); init_var(&arg2); set_var_from_num(num1, &arg1); set_var_from_num(num2, &arg2); result = cmp_var(&arg1, &arg2); free_var(&arg1); free_var(&arg2); return (result < 0);}boolnumeric_le(Numeric num1, Numeric num2){ int result; NumericVar arg1; NumericVar arg2; if (num1 == NULL || num2 == NULL) return FALSE; if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) return FALSE; init_var(&arg1); init_var(&arg2); set_var_from_num(num1, &arg1); set_var_from_num(num2, &arg2); result = cmp_var(&arg1, &arg2); free_var(&arg1); free_var(&arg2); return (result <= 0);}/* ---------------------------------------------------------------------- * * Arithmetic base functions * * ---------------------------------------------------------------------- *//* ---------- * numeric_add() - * * Add two numerics * ---------- */Numericnumeric_add(Numeric num1, Numeric num2){ NumericVar arg1; NumericVar arg2; NumericVar result; Numeric res; /* ---------- * Handle NULL * ---------- */ if (num1 == NULL || num2 == NULL) return NULL; /* ---------- * Handle NaN * ---------- */ if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) return make_result(&const_nan); /* ---------- * Unpack the values, let add_var() compute the result * and return it. The internals of add_var() will automatically * set the correct result and display scales in the result. * ---------- */ init_var(&arg1); init_var(&arg2); init_var(&result); set_var_from_num(num1, &arg1); set_var_from_num(num2, &arg2); add_var(&arg1, &arg2, &result); res = make_result(&result); free_var(&arg1); free_var(&arg2); free_var(&result); return res;}/* ---------- * numeric_sub() - * * Subtract one numeric from another * ---------- */Numericnumeric_sub(Numeric num1, Numeric num2){ NumericVar arg1; NumericVar arg2; NumericVar result; Numeric res; /* ---------- * Handle NULL * ---------- */ if (num1 == NULL || num2 == NULL) return NULL; /* ---------- * Handle NaN * ---------- */ if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) return make_result(&const_nan); /* ---------- * Unpack the two arguments, let sub_var() compute the * result and return it. * ---------- */ init_var(&arg1); init_var(&arg2); init_var(&result); set_var_from_num(num1, &arg1); set_var_from_num(num2, &arg2); sub_var(&arg1, &arg2, &result); res = make_result(&result); free_var(&arg1); free_var(&arg2); free_var(&result); return res;}/* ---------- * numeric_mul() - * * Calculate the product of two numerics * ---------- */Numericnumeric_mul(Numeric num1, Numeric num2){ NumericVar arg1; NumericVar arg2; NumericVar result; Numeric res; /* ---------- * Handle NULL * ---------- */ if (num1 == NULL || num2 == NULL) return NULL; /* ---------- * Handle NaN * ---------- */ if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) return make_result(&const_nan); /* ---------- * Unpack the arguments, let mul_var() compute the result * and return it. Unlike add_var() and sub_var(), mul_var() * will round the result to the scale stored in global_rscale. * In the case of numeric_mul(), which is invoked for the * * operator on numerics, we set it to the exact representation * for the product (rscale = sum(rscale of arg1, rscale of arg2) * and the same for the dscale). * ---------- */ init_var(&arg1); init_var(&arg2); init_var(&result); set_var_from_num(num1, &arg1); set_var_from_num(num2, &arg2); global_rscale = arg1.rscale + arg2.rscale; mul_var(&arg1, &arg2, &result); result.dscale = arg1.dscale + arg2.dscale; res = make_result(&result); free_var(&arg1); free_var(&arg2); free_var(&result); return res;}/* ---------- * numeric_div() - * * Divide one numeric into another * ---------- */Numericnumeric_div(Numeric num1, Numeric num2){ NumericVar arg1; NumericVar arg2; NumericVar result; Numeric res; int res_dscale; /* ---------- * Handle NULL * ---------- */ if (num1 == NULL || num2 == NULL) return NULL; /* ---------- * Handle NaN * ---------- */ if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) return make_result(&const_nan); /* ---------- * Unpack the arguments * ---------- */ init_var(&arg1); init_var(&arg2); init_var(&result); set_var_from_num(num1, &arg1); set_var_from_num(num2, &arg2); /* ---------- * The result scale of a division isn't specified in any * SQL standard. For Postgres it is the following (where * SR, DR are the result- and display-scales of the returned * value, S1, D1, S2 and D2 are the scales of the two arguments, * The minimum and maximum scales are compile time options from * numeric.h): * * DR = MIN(MAX(D1 + D2, MIN_DISPLAY_SCALE)) * SR = MIN(MAX(MAX(S1 + S2, MIN_RESULT_SCALE), DR + 4), MAX_RESULT_SCALE) * * By default, any result is computed with a minimum of 34 digits * after the decimal point or at least with 4 digits more than * displayed. * ---------- */ res_dscale = MAX(arg1.dscale + arg2.dscale, NUMERIC_MIN_DISPLAY_SCALE); res_dscale = MIN(res_dscale, NUMERIC_MAX_DISPLAY_SCALE); global_rscale = MAX(arg1.rscale + arg2.rscale, NUMERIC_MIN_RESULT_SCALE); global_rscale = MAX(global_rscale, res_dscale + 4); global_rscale = MIN(global_rscale, NUMERIC_MAX_RESULT_SCALE); /* ---------- * Do the divide, set the display scale and return the result * ---------- */ div_var(&arg1, &arg2, &result); result.dscale = res_dscale; res = make_result(&result); free_var(&arg1); free_var(&arg2); free_var(&result); return res;}/* ---------- * numeric_mod() - * * Calculate the modulo of two numerics * ---------- */Numericnumeric_mod(Numeric num1, Numeric num2){ Numeric res; NumericVar arg1; NumericVar arg2; NumericVar result; if (num1 == NULL || num2 == NULL) return NULL; if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) return make_result(&const_nan); init_var(&arg1); init_var(&arg2); init_var(&result); set_var_from_num(num1, &arg1); set_var_from_num(num2, &arg2); mod_var(&arg1, &arg2, &result); result.dscale = result.rscale; res = make_result(&result); free_var(&result); free_var(&arg2); free_var(&arg1); return res;}/* ---------- * numeric_inc() - * * Increment a number by one * ---------- */Numericnumeric_inc(Numeric num){ NumericVar arg; Numeric res; /* ---------- * Handle NULL * ---------- */ if (num == NULL) return NULL; /* ---------- * Handle NaN * ---------- */ if (NUMERIC_IS_NAN(num)) return make_result(&const_nan); /* ---------- * Compute the result and return it * ---------- */ init_var(&arg); set_var_from_num(num, &arg); add_var(&arg, &const_one, &arg); res = make_result(&arg); free_var(&arg); return res;}/* ---------- * numeric_dec() - * * Decrement a number by one * ---------- */Numericnumeric_dec(Numeric num){ NumericVar arg; Numeric res; /* ---------- * Handle NULL * ---------- */ if (num == NULL) return NULL; /* ---------- * Handle NaN * ---------- */ if (NUMERIC_IS_NAN(num)) return make_result(&const_nan); /* ---------- * Compute the result and return it * ---------- */ init_var(&arg); set_var_from_num(num, &arg); sub_var(&arg, &const_one, &arg); res = make_result(&arg); free_var(&arg); return res;}/* ---------- * numeric_smaller() - * * Return the smaller of two numbers * ---------- */Numericnumeric_smaller(Numeric num1, Numeric num2){ NumericVar arg1; NumericVar arg2; Numeric res; /* ---------- * Handle NULL * ---------- */ if (num1 == NULL || num2 == NULL) return NULL; /* ---------- * Handle NaN * ---------- */ if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) return make_result(&const_nan); /* ---------- * Unpack the values, and decide which is the smaller one * ---------- */ init_var(&arg1); init_var(&arg2); set_var_from_num(num1, &arg1); set_var_from_num(num2, &arg2); if (cmp_var(&arg1, &arg2) <= 0) res = make_result(&arg1); else res = make_result(&arg2); free_var(&arg1); free_var(&arg2); return res;}/* ---------- * numeric_larger() - * * Return the larger of two numbers * ---------- */Numericnumeric_larger(Numeric num1, Numeric num2){ NumericVar arg1; NumericVar arg2; Numeric res; /* ---------- * Handle NULL * ---------- */ if (num1 == NULL || num2 == NULL) return NULL; /* ---------- * Handle NaN * ---------- */ if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) return make_result(&const_nan); /* ---------- * Unpack the values, and decide which is the larger one * ---------- */ init_var(&arg1); init_var(&arg2); set_var_from_num(num1, &arg1); set_var_from_num(num2, &arg2); if (cmp_var(&arg1, &arg2) >= 0) res = make_result(&arg1); else res = make_result(&arg2); free_var(&arg1); free_var(&arg2); return res;}/* ---------------------------------------------------------------------- * * Complex math functions * * ---------------------------------------------------------------------- *//* ---------- * numeric_sqrt() - * * Compute the square root of a numeric. * ---------- */Numericnumeric_sqrt(Numeric num){ Numeric res; NumericVar arg; NumericVar result; int res_dscale; /* ---------- * Handle NULL * ---------- */ if (num == NULL) return NULL; /* ---------- * Handle NaN * ---------- */ if (NUMERIC_IS_NAN(num)) return make_result(&const_nan); /* ---------- * Unpack the argument, determine the scales like for divide, * let sqrt_var() do the calculation and return the result. * ---------- */ init_var(&arg); init_var(&result); set_var_from_num(num, &arg); res_dscale = MAX(arg.dscale, NUMERIC_MIN_DISPLAY_SCALE); res_dscale = MIN(res_dscale, NUMERIC_MAX_DISPLAY_SCALE); global_rscale = MAX(arg.rscale, NUMERIC_MIN_RESULT_SCALE); global_rscale = MAX(global_rscale, res_dscale + 4); global_rscale = MIN(global_rscale, NUMERIC_MAX_RESULT_SCALE); sqrt_var(&arg, &result); result.dscale = res_dscale; res = make_result(&result); free_var(&result); free_var(&arg); return res;}/* ---------- * numeric_exp() - * * Raise e to the power of x * ---------- */Numericnumeric_exp(Numeric num)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -