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 as published by 5 the Free Software Foundation; version 2 of the License. 6 7 This program is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 GNU General Public License for more details. 11 12 You should have received a copy of the GNU General Public License 13 along with this program; if not, write to the Free Software 14 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ 15 16 #ifndef _decimal_h 17 #define _decimal_h 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 typedef enum 24 {TRUNCATE=0, HALF_EVEN, HALF_UP, CEILING, FLOOR} 25 decimal_round_mode; 26 typedef int32 decimal_digit_t; 27 28 /** 29 intg is the number of *decimal* digits (NOT number of decimal_digit_t's !) 30 before the point 31 frac is the number of decimal digits after the point 32 len is the length of buf (length of allocated space) in decimal_digit_t's, 33 not in bytes 34 sign false means positive, true means negative 35 buf is an array of decimal_digit_t's 36 */ 37 typedef struct st_decimal_t { 38 int intg, frac, len; 39 my_bool sign; 40 decimal_digit_t *buf; 41 } decimal_t; 42 43 int internal_str2dec(const char *from, decimal_t *to, char **end, 44 my_bool fixed); 45 int decimal2string(const decimal_t *from, char *to, int *to_len, 46 int fixed_precision, int fixed_decimals, 47 char filler); 48 int decimal2ulonglong(const decimal_t *from, ulonglong *to); 49 int ulonglong2decimal(ulonglong from, decimal_t *to); 50 int decimal2longlong(const decimal_t *from, longlong *to); 51 int longlong2decimal(longlong from, decimal_t *to); 52 int decimal2double(const decimal_t *from, double *to); 53 int double2decimal(double from, decimal_t *to); 54 int decimal_actual_fraction(const decimal_t *from); 55 int decimal2bin(const decimal_t *from, uchar *to, int precision, int scale); 56 int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale); 57 58 int decimal_size(int precision, int scale); 59 int decimal_bin_size(int precision, int scale); 60 int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, 61 int param); 62 63 int decimal_intg(const decimal_t *from); 64 int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to); 65 int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to); 66 int decimal_cmp(const decimal_t *from1, const decimal_t *from2); 67 int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to); 68 int decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, 69 int scale_incr); 70 int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to); 71 int decimal_round(const decimal_t *from, decimal_t *to, int new_scale, 72 decimal_round_mode mode); 73 int decimal_is_zero(const decimal_t *from); 74 void max_decimal(int precision, int frac, decimal_t *to); 75 76 #define string2decimal(A,B,C) internal_str2dec((A), (B), (C), 0) 77 #define string2decimal_fixed(A,B,C) internal_str2dec((A), (B), (C), 1) 78 79 /* set a decimal_t to zero */ 80 81 #define decimal_make_zero(dec) do { \ 82 (dec)->buf[0]=0; \ 83 (dec)->intg=1; \ 84 (dec)->frac=0; \ 85 (dec)->sign=0; \ 86 } while(0) 87 88 /* 89 returns the length of the buffer to hold string representation 90 of the decimal (including decimal dot, possible sign and \0) 91 */ 92 93 #define decimal_string_size(dec) (((dec)->intg ? (dec)->intg : 1) + \ 94 (dec)->frac + ((dec)->frac > 0) + 2) 95 96 /* negate a decimal */ 97 #define decimal_neg(dec) do { (dec)->sign^=1; } while(0) 98 99 /* 100 conventions: 101 102 decimal_smth() == 0 -- everything's ok 103 decimal_smth() <= 1 -- result is usable, but precision loss is possible 104 decimal_smth() <= 2 -- result can be unusable, most significant digits 105 could've been lost 106 decimal_smth() > 2 -- no result was generated 107 */ 108 109 #define E_DEC_OK 0 110 #define E_DEC_TRUNCATED 1 111 #define E_DEC_OVERFLOW 2 112 #define E_DEC_DIV_ZERO 4 113 #define E_DEC_BAD_NUM 8 114 #define E_DEC_OOM 16 115 116 #define E_DEC_ERROR 31 117 #define E_DEC_FATAL_ERROR 30 118 119 #ifdef __cplusplus 120 } 121 #endif 122 123 #endif 124 125