1 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License, version 2.0, 5 as published by the Free Software Foundation. 6 7 This program is also distributed with certain software (including 8 but not limited to OpenSSL) that is licensed under separate terms, 9 as designated in a particular file or component or in included license 10 documentation. The authors of MySQL hereby grant you an additional 11 permission to link the program and your derivative works with the 12 separately licensed software that they have included with MySQL. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License, version 2.0, for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 22 23 #ifndef _decimal_h 24 #define _decimal_h 25 26 typedef enum 27 {TRUNCATE=0, HALF_EVEN, HALF_UP, CEILING, FLOOR} 28 decimal_round_mode; 29 typedef int32 decimal_digit_t; 30 31 /** 32 intg is the number of *decimal* digits (NOT number of decimal_digit_t's !) 33 before the point 34 frac is the number of decimal digits after the point 35 len is the length of buf (length of allocated space) in decimal_digit_t's, 36 not in bytes 37 sign false means positive, true means negative 38 buf is an array of decimal_digit_t's 39 */ 40 typedef struct st_decimal_t { 41 int intg, frac, len; 42 my_bool sign; 43 decimal_digit_t *buf; 44 } decimal_t; 45 46 int internal_str2dec(const char *from, decimal_t *to, char **end, 47 my_bool fixed); 48 int decimal2string(const decimal_t *from, char *to, int *to_len, 49 int fixed_precision, int fixed_decimals, 50 char filler); 51 int decimal2ulonglong(decimal_t *from, ulonglong *to); 52 int ulonglong2decimal(ulonglong from, decimal_t *to); 53 int decimal2longlong(decimal_t *from, longlong *to); 54 int longlong2decimal(longlong from, decimal_t *to); 55 int decimal2double(const decimal_t *from, double *to); 56 int double2decimal(double from, decimal_t *to); 57 int decimal_actual_fraction(decimal_t *from); 58 int decimal2bin(decimal_t *from, uchar *to, int precision, int scale); 59 int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale); 60 61 /** 62 Convert decimal to lldiv_t. 63 The integer part is stored in to->quot. 64 The fractional part is multiplied to 10^9 and stored to to->rem. 65 @param from Decimal value 66 @param to lldiv_t value 67 @retval 0 on success 68 @retval !0 in error 69 */ 70 int decimal2lldiv_t(const decimal_t *from, lldiv_t *to); 71 72 /** 73 Convert doube to lldiv_t. 74 The integer part is stored in to->quot. 75 The fractional part is multiplied to 10^9 and stored to to->rem. 76 @param from Decimal value 77 @param to lldiv_t value 78 @retval 0 on success 79 @retval !0 in error 80 */ 81 82 int double2lldiv_t(double from, lldiv_t *to); 83 int decimal_size(int precision, int scale); 84 int decimal_bin_size(int precision, int scale); 85 int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, 86 int param); 87 88 int decimal_intg(const decimal_t *from); 89 int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to); 90 int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to); 91 int decimal_cmp(const decimal_t *from1, const decimal_t *from2); 92 int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to); 93 int decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, 94 int scale_incr); 95 int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to); 96 int decimal_round(const decimal_t *from, decimal_t *to, int new_scale, 97 decimal_round_mode mode); 98 int decimal_is_zero(const decimal_t *from); 99 void max_decimal(int precision, int frac, decimal_t *to); 100 101 #define string2decimal(A,B,C) internal_str2dec((A), (B), (C), 0) 102 #define string2decimal_fixed(A,B,C) internal_str2dec((A), (B), (C), 1) 103 104 /* set a decimal_t to zero */ 105 106 #define decimal_make_zero(dec) do { \ 107 (dec)->buf[0]=0; \ 108 (dec)->intg=1; \ 109 (dec)->frac=0; \ 110 (dec)->sign=0; \ 111 } while(0) 112 113 /* 114 returns the length of the buffer to hold string representation 115 of the decimal (including decimal dot, possible sign and \0) 116 */ 117 118 #define decimal_string_size(dec) (((dec)->intg ? (dec)->intg : 1) + \ 119 (dec)->frac + ((dec)->frac > 0) + 2) 120 121 /* negate a decimal */ 122 #define decimal_neg(dec) do { (dec)->sign^=1; } while(0) 123 124 /* 125 conventions: 126 127 decimal_smth() == 0 -- everything's ok 128 decimal_smth() <= 1 -- result is usable, but precision loss is possible 129 decimal_smth() <= 2 -- result can be unusable, most significant digits 130 could've been lost 131 decimal_smth() > 2 -- no result was generated 132 */ 133 134 #define E_DEC_OK 0 135 #define E_DEC_TRUNCATED 1 136 #define E_DEC_OVERFLOW 2 137 #define E_DEC_DIV_ZERO 4 138 #define E_DEC_BAD_NUM 8 139 #define E_DEC_OOM 16 140 141 #define E_DEC_ERROR 31 142 #define E_DEC_FATAL_ERROR 30 143 144 #endif 145 146