This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
| #define decimal_make_zero | ( | dec | ) |
Value:
do { \ (dec)->buf[0]=0; \ (dec)->intg=1; \ (dec)->frac=0; \ (dec)->sign=0; \ } while(0)
Definition at line 69 of file decimal.h.
Referenced by bin2decimal(), decimal_mul(), decimal_round(), decimal_shift(), do_div_mod(), do_sub(), internal_str2dec(), and my_decimal_set_zero().
| #define decimal_neg | ( | dec | ) | do { (dec)->sign^=1; } while(0) |
| #define decimal_string_size | ( | dec | ) |
Value:
(((dec)->intg ? (dec)->intg : 1) + \
(dec)->frac + ((dec)->frac > 0) + 2)
Definition at line 81 of file decimal.h.
Referenced by my_decimal_max_length(), and my_decimal_string_length().
| #define E_DEC_BAD_NUM 8 |
Definition at line 101 of file decimal.h.
Referenced by bin2decimal(), decimal_operation_results(), internal_str2dec(), Field_new_decimal::store(), and Item::val_decimal_from_string().
| #define E_DEC_DIV_ZERO 4 |
Definition at line 100 of file decimal.h.
Referenced by Item_func_mod::decimal_op(), Item_func_div::decimal_op(), decimal_operation_results(), and do_div_mod().
| #define E_DEC_ERROR 31 |
| #define E_DEC_FATAL_ERROR 30 |
Definition at line 105 of file decimal.h.
Referenced by field_decimal::add(), Item_sum_variance::add(), Item_sum_sum::add(), Hybrid_type_traits_decimal::add(), field_decimal::avg(), collect_decimal(), Item_func_round::decimal_op(), Item_func_floor::decimal_op(), Item_func_ceiling::decimal_op(), Item_func_mod::decimal_op(), Item_func_div::decimal_op(), Item_func_mul::decimal_op(), Item_func_minus::decimal_op(), Item_func_plus::decimal_op(), Hybrid_type_traits_fast_decimal::div(), Hybrid_type_traits_decimal::div(), field_decimal::get_max_arg(), field_decimal::get_min_arg(), Item_func_floor::int_op(), Item_func_ceiling::int_op(), Item_decimal::Item_decimal(), make_sortkey(), Item_decimal::print(), Item_param::query_val_str(), Item_sum_avg::reset_field(), Item_sum_variance::reset_field(), Item_param::set_decimal(), field_decimal::std(), Field_new_decimal::store(), Field_longstr::store_decimal(), Field_real::store_decimal(), Field_str::store_decimal(), Protocol_prep::store_decimal(), Protocol_simple::store_decimal(), Field_new_decimal::store_value(), Item_sum_avg::update_field(), Item_sum_sum::update_field(), Item_sum_variance::update_field(), Item_proc_real::val_decimal(), Item_proc_int::val_decimal(), Item_proc_string::val_decimal(), Item_variance_field::val_decimal(), Item_std_field::val_decimal(), Item_avg_field::val_decimal(), Item_sum_hybrid::val_decimal(), Item_sum_variance::val_decimal(), Item_sum_avg::val_decimal(), Item_in_subselect::val_decimal(), Item_exists_subselect::val_decimal(), Item_str_func::val_decimal(), Item_decimal_typecast::val_decimal(), Item_func_numhybrid::val_decimal(), Item_real_func::val_decimal(), Item_func::val_decimal(), Hybrid_type_traits_integer::val_decimal(), Item_cache_str::val_decimal(), Item_cache_real::val_decimal(), Item_cache_int::val_decimal(), Item_hex_string::val_decimal(), Item_copy_string::val_decimal(), Item_param::val_decimal(), Item_float::val_decimal(), Item_int::val_decimal(), Hybrid_type_traits::val_decimal(), Field_bit::val_decimal(), Field_blob::val_decimal(), Field_varstring::val_decimal(), Field_string::val_decimal(), Field_real::val_decimal(), Field_new_decimal::val_decimal(), Field_str::val_decimal(), Field_num::val_decimal(), Item::val_decimal_from_int(), Item::val_decimal_from_real(), Item::val_decimal_from_string(), Item_sum_hybrid::val_int(), Item_sum_sum::val_int(), Item_decimal_typecast::val_int(), Item_func_numhybrid::val_int(), Item_func_interval::val_int(), Item_cache_decimal::val_int(), Item_param::val_int(), Item_decimal::val_int(), Hybrid_type_traits_decimal::val_int(), Field_new_decimal::val_int(), Item::val_int_from_decimal(), Item_std_field::val_real(), Item_sum_hybrid::val_real(), Item_sum_sum::val_real(), Item_decimal_typecast::val_real(), Item_func_numhybrid::val_real(), Item_cache_decimal::val_real(), Item_param::val_real(), Item_decimal::val_real(), Hybrid_type_traits_decimal::val_real(), Field_new_decimal::val_real(), Item::val_real_from_decimal(), Item_sum_hybrid::val_str(), Item_func_format::val_str(), Item_func_min_max::val_str(), Item_decimal_typecast::val_str(), Item_func_numhybrid::val_str(), Item_cache_decimal::val_str(), Item_param::val_str(), Item_decimal::val_str(), Hybrid_type_traits_decimal::val_str(), and Item::val_string_from_decimal().
| #define E_DEC_OK 0 |
Definition at line 97 of file decimal.h.
Referenced by bin2decimal(), decimal2bin(), decimal2double(), decimal2longlong(), decimal2string(), decimal2ulonglong(), Item_func_mod::decimal_op(), decimal_operation_results(), decimal_round(), decimal_shift(), do_div_mod(), do_sub(), my_decimal2binary(), and ull2dec().
| #define E_DEC_OOM 16 |
Definition at line 102 of file decimal.h.
Referenced by decimal_operation_results(), do_div_mod(), internal_str2dec(), and my_decimal2string().
| #define E_DEC_OVERFLOW 2 |
Definition at line 99 of file decimal.h.
Referenced by Field::check_overflow(), check_result_and_overflow(), Field::convert_decimal2longlong(), decimal2bin(), decimal2longlong(), decimal2string(), decimal2ulonglong(), decimal_mul(), decimal_operation_results(), decimal_shift(), do_add(), do_div_mod(), internal_str2dec(), Field_new_decimal::store(), Field_str::store_decimal(), Field_new_decimal::store_value(), ull2dec(), and Field::warn_if_overflow().
| #define E_DEC_TRUNCATED 1 |
Definition at line 98 of file decimal.h.
Referenced by Field::convert_decimal2longlong(), decimal2bin(), decimal2longlong(), decimal2string(), decimal2ulonglong(), Item_func_mod::decimal_op(), decimal_operation_results(), decimal_round(), decimal_shift(), do_div_mod(), internal_str2dec(), my_decimal2binary(), Field_new_decimal::store(), str2my_decimal(), and Field::warn_if_overflow().
| typedef int32 decimal_digit_t |
| typedef struct st_decimal_t decimal_t |
| enum decimal_round_mode |
| int bin2decimal | ( | char * | from, | |
| decimal_t * | to, | |||
| int | precision, | |||
| int | scale | |||
| ) |
Definition at line 1306 of file decimal.c.
References buf, DBUG_ASSERT, decimal_bin_size(), decimal_make_zero, dig2bytes, DIG_MAX, DIG_PER_DEC1, E_DEC_BAD_NUM, E_DEC_OK, err, error, FIX_INTG_FRAC_ERROR, mask, memcpy, mi_sint1korr, mi_sint2korr, mi_sint3korr, mi_sint4korr, my_afree, my_alloca, powers10, sanity, stop(), to, unlikely, and x.
01307 { 01308 int error=E_DEC_OK, intg=precision-scale, 01309 intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1, 01310 intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1, 01311 intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0); 01312 dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1; 01313 char *stop; 01314 char *d_copy; 01315 int bin_size= decimal_bin_size(precision, scale); 01316 01317 sanity(to); 01318 d_copy= (char *)my_alloca(bin_size); 01319 memcpy(d_copy, from, bin_size); 01320 d_copy[0]^= 0x80; 01321 from= d_copy; 01322 01323 FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error); 01324 if (unlikely(error)) 01325 { 01326 if (intg1 < intg0+(intg0x>0)) 01327 { 01328 from+=dig2bytes[intg0x]+sizeof(dec1)*(intg0-intg1); 01329 frac0=frac0x=intg0x=0; 01330 intg0=intg1; 01331 } 01332 else 01333 { 01334 frac0x=0; 01335 frac0=frac1; 01336 } 01337 } 01338 01339 to->sign=(mask != 0); 01340 to->intg=intg0*DIG_PER_DEC1+intg0x; 01341 to->frac=frac0*DIG_PER_DEC1+frac0x; 01342 01343 if (intg0x) 01344 { 01345 int i=dig2bytes[intg0x]; 01346 dec1 x; 01347 switch (i) 01348 { 01349 case 1: x=mi_sint1korr(from); break; 01350 case 2: x=mi_sint2korr(from); break; 01351 case 3: x=mi_sint3korr(from); break; 01352 case 4: x=mi_sint4korr(from); break; 01353 default: DBUG_ASSERT(0); 01354 } 01355 from+=i; 01356 *buf=x ^ mask; 01357 if (((ulonglong)*buf) >= (ulonglong) powers10[intg0x+1]) 01358 goto err; 01359 if (buf > to->buf || *buf != 0) 01360 buf++; 01361 else 01362 to->intg-=intg0x; 01363 } 01364 for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1)) 01365 { 01366 DBUG_ASSERT(sizeof(dec1) == 4); 01367 *buf=mi_sint4korr(from) ^ mask; 01368 if (((uint32)*buf) > DIG_MAX) 01369 goto err; 01370 if (buf > to->buf || *buf != 0) 01371 buf++; 01372 else 01373 to->intg-=DIG_PER_DEC1; 01374 } 01375 DBUG_ASSERT(to->intg >=0); 01376 for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1)) 01377 { 01378 DBUG_ASSERT(sizeof(dec1) == 4); 01379 *buf=mi_sint4korr(from) ^ mask; 01380 if (((uint32)*buf) > DIG_MAX) 01381 goto err; 01382 buf++; 01383 } 01384 if (frac0x) 01385 { 01386 int i=dig2bytes[frac0x]; 01387 dec1 x; 01388 switch (i) 01389 { 01390 case 1: x=mi_sint1korr(from); break; 01391 case 2: x=mi_sint2korr(from); break; 01392 case 3: x=mi_sint3korr(from); break; 01393 case 4: x=mi_sint4korr(from); break; 01394 default: DBUG_ASSERT(0); 01395 } 01396 *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x]; 01397 if (((uint32)*buf) > DIG_MAX) 01398 goto err; 01399 buf++; 01400 } 01401 my_afree(d_copy); 01402 return error; 01403 01404 err: 01405 my_afree(d_copy); 01406 decimal_make_zero(((decimal_t*) to)); 01407 return(E_DEC_BAD_NUM); 01408 }
Here is the call graph for this function:

| int decimal2bin | ( | decimal_t * | from, | |
| char * | to, | |||
| int | precision, | |||
| int | scale | |||
| ) |
Definition at line 1171 of file decimal.c.
References DBUG_ASSERT, dig2bytes, DIG_PER_DEC1, E_DEC_OK, E_DEC_OVERFLOW, E_DEC_TRUNCATED, error, from, mask, mi_int1store, mi_int2store, mi_int3store, mi_int4store, powers10, remove_leading_zeroes(), unlikely, and x.
01172 { 01173 dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1; 01174 int error=E_DEC_OK, intg=precision-frac, 01175 isize1, intg1, intg1x, from_intg, 01176 intg0=intg/DIG_PER_DEC1, 01177 frac0=frac/DIG_PER_DEC1, 01178 intg0x=intg-intg0*DIG_PER_DEC1, 01179 frac0x=frac-frac0*DIG_PER_DEC1, 01180 frac1=from->frac/DIG_PER_DEC1, 01181 frac1x=from->frac-frac1*DIG_PER_DEC1, 01182 isize0=intg0*sizeof(dec1)+dig2bytes[intg0x], 01183 fsize0=frac0*sizeof(dec1)+dig2bytes[frac0x], 01184 fsize1=frac1*sizeof(dec1)+dig2bytes[frac1x]; 01185 const int orig_isize0= isize0; 01186 const int orig_fsize0= fsize0; 01187 char *orig_to= to; 01188 01189 buf1= remove_leading_zeroes(from, &from_intg); 01190 01191 if (unlikely(from_intg+fsize1==0)) 01192 { 01193 mask=0; /* just in case */ 01194 intg=1; 01195 buf1=&mask; 01196 } 01197 01198 intg1=from_intg/DIG_PER_DEC1; 01199 intg1x=from_intg-intg1*DIG_PER_DEC1; 01200 isize1=intg1*sizeof(dec1)+dig2bytes[intg1x]; 01201 01202 if (intg < from_intg) 01203 { 01204 buf1+=intg1-intg0+(intg1x>0)-(intg0x>0); 01205 intg1=intg0; intg1x=intg0x; 01206 error=E_DEC_OVERFLOW; 01207 } 01208 else if (isize0 > isize1) 01209 { 01210 while (isize0-- > isize1) 01211 *to++= (char)mask; 01212 } 01213 if (fsize0 < fsize1) 01214 { 01215 frac1=frac0; frac1x=frac0x; 01216 error=E_DEC_TRUNCATED; 01217 } 01218 else if (fsize0 > fsize1 && frac1x) 01219 { 01220 if (frac0 == frac1) 01221 { 01222 frac1x=frac0x; 01223 fsize0= fsize1; 01224 } 01225 else 01226 { 01227 frac1++; 01228 frac1x=0; 01229 } 01230 } 01231 01232 /* intg1x part */ 01233 if (intg1x) 01234 { 01235 int i=dig2bytes[intg1x]; 01236 dec1 x=(*buf1++ % powers10[intg1x]) ^ mask; 01237 switch (i) 01238 { 01239 case 1: mi_int1store(to, x); break; 01240 case 2: mi_int2store(to, x); break; 01241 case 3: mi_int3store(to, x); break; 01242 case 4: mi_int4store(to, x); break; 01243 default: DBUG_ASSERT(0); 01244 } 01245 to+=i; 01246 } 01247 01248 /* intg1+frac1 part */ 01249 for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=sizeof(dec1)) 01250 { 01251 dec1 x=*buf1++ ^ mask; 01252 DBUG_ASSERT(sizeof(dec1) == 4); 01253 mi_int4store(to, x); 01254 } 01255 01256 /* frac1x part */ 01257 if (frac1x) 01258 { 01259 dec1 x; 01260 int i=dig2bytes[frac1x], 01261 lim=(frac1 < frac0 ? DIG_PER_DEC1 : frac0x); 01262 while (frac1x < lim && dig2bytes[frac1x] == i) 01263 frac1x++; 01264 x=(*buf1 / powers10[DIG_PER_DEC1 - frac1x]) ^ mask; 01265 switch (i) 01266 { 01267 case 1: mi_int1store(to, x); break; 01268 case 2: mi_int2store(to, x); break; 01269 case 3: mi_int3store(to, x); break; 01270 case 4: mi_int4store(to, x); break; 01271 default: DBUG_ASSERT(0); 01272 } 01273 to+=i; 01274 } 01275 if (fsize0 > fsize1) 01276 { 01277 char *to_end= orig_to + orig_fsize0 + orig_isize0; 01278 01279 while (fsize0-- > fsize1 && to < to_end) 01280 *to++=(uchar)mask; 01281 } 01282 orig_to[0]^= 0x80; 01283 01284 /* Check that we have written the whole decimal and nothing more */ 01285 DBUG_ASSERT(to == orig_to + orig_fsize0 + orig_isize0); 01286 return error; 01287 }
Here is the call graph for this function:

| int decimal2double | ( | decimal_t * | from, | |
| double * | to | |||
| ) |
Definition at line 947 of file decimal.c.
References buf, DIG_BASE, DIG_PER_DEC1, E_DEC_OK, from, and x.
00948 { 00949 double x=0, t=DIG_BASE; 00950 int intg, frac; 00951 dec1 *buf=from->buf; 00952 00953 for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1) 00954 x=x*DIG_BASE + *buf++; 00955 for (frac=from->frac; frac > 0; frac-=DIG_PER_DEC1, t*=DIG_BASE) 00956 x+=*buf++/t; 00957 *to=from->sign ? -x : x; 00958 return E_DEC_OK; 00959 }
Definition at line 1056 of file decimal.c.
References buf, DIG_BASE, DIG_PER_DEC1, E_DEC_OK, E_DEC_OVERFLOW, E_DEC_TRUNCATED, from, LONGLONG_MAX, LONGLONG_MIN, unlikely, and x.
01057 { 01058 dec1 *buf=from->buf; 01059 longlong x=0; 01060 int intg, frac; 01061 01062 for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1) 01063 { 01064 longlong y=x; 01065 /* 01066 Attention: trick! 01067 we're calculating -|from| instead of |from| here 01068 because |LONGLONG_MIN| > LONGLONG_MAX 01069 so we can convert -9223372036854775808 correctly 01070 */ 01071 x=x*DIG_BASE - *buf++; 01072 if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y)) 01073 { 01074 *to= from->sign ? y : -y; 01075 return E_DEC_OVERFLOW; 01076 } 01077 } 01078 /* boundary case: 9223372036854775808 */ 01079 if (unlikely(from->sign==0 && x == LONGLONG_MIN)) 01080 { 01081 *to= LONGLONG_MAX; 01082 return E_DEC_OVERFLOW; 01083 } 01084 01085 *to=from->sign ? x : -x; 01086 for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1) 01087 if (*buf++) 01088 return E_DEC_TRUNCATED; 01089 return E_DEC_OK; 01090 }
| int decimal2string | ( | decimal_t * | from, | |
| char * | to, | |||
| int * | to_len, | |||
| int | fixed_precision, | |||
| int | fixed_decimals, | |||
| char | filler | |||
| ) |
Definition at line 332 of file decimal.c.
References buf, DBUG_ASSERT, DIG_MASK, DIG_PER_DEC1, E_DEC_OK, E_DEC_OVERFLOW, E_DEC_TRUNCATED, error, mySTL::fill(), from, min, remove_leading_zeroes(), ROUND_UP, test, unlikely, and x.
00335 { 00336 int len, intg, frac= from->frac, i, intg_len, frac_len, fill; 00337 /* number digits before decimal point */ 00338 int fixed_intg= (fixed_precision ? 00339 (fixed_precision - fixed_decimals) : 0); 00340 int error=E_DEC_OK; 00341 char *s=to; 00342 dec1 *buf, *buf0=from->buf, tmp; 00343 00344 DBUG_ASSERT(*to_len >= 2+from->sign); 00345 00346 /* removing leading zeroes */ 00347 buf0= remove_leading_zeroes(from, &intg); 00348 if (unlikely(intg+frac==0)) 00349 { 00350 intg=1; 00351 tmp=0; 00352 buf0=&tmp; 00353 } 00354 00355 if (!(intg_len= fixed_precision ? fixed_intg : intg)) 00356 intg_len= 1; 00357 frac_len= fixed_precision ? fixed_decimals : frac; 00358 len= from->sign + intg_len + test(frac) + frac_len; 00359 if (fixed_precision) 00360 { 00361 if (frac > fixed_decimals) 00362 { 00363 error= E_DEC_TRUNCATED; 00364 frac= fixed_decimals; 00365 } 00366 if (intg > fixed_intg) 00367 { 00368 error= E_DEC_OVERFLOW; 00369 intg= fixed_intg; 00370 } 00371 } 00372 else if (unlikely(len > --*to_len)) /* reserve one byte for \0 */ 00373 { 00374 int i=len-*to_len; 00375 error= (frac && i <= frac + 1) ? E_DEC_TRUNCATED : E_DEC_OVERFLOW; 00376 if (frac && i >= frac + 1) i--; 00377 if (i > frac) 00378 { 00379 intg-= i-frac; 00380 frac= 0; 00381 } 00382 else 00383 frac-=i; 00384 len= from->sign + intg_len + test(frac) + frac_len; 00385 } 00386 *to_len=len; 00387 s[len]=0; 00388 00389 if (from->sign) 00390 *s++='-'; 00391 00392 if (frac) 00393 { 00394 char *s1= s + intg_len; 00395 fill= frac_len - frac; 00396 buf=buf0+ROUND_UP(intg); 00397 *s1++='.'; 00398 for (; frac>0; frac-=DIG_PER_DEC1) 00399 { 00400 dec1 x=*buf++; 00401 for (i=min(frac, DIG_PER_DEC1); i; i--) 00402 { 00403 dec1 y=x/DIG_MASK; 00404 *s1++='0'+(uchar)y; 00405 x-=y*DIG_MASK; 00406 x*=10; 00407 } 00408 } 00409 for(; fill; fill--) 00410 *s1++=filler; 00411 } 00412 00413 fill= intg_len - intg; 00414 if (intg == 0) 00415 fill--; /* symbol 0 before digital point */ 00416 for(; fill; fill--) 00417 *s++=filler; 00418 if (intg) 00419 { 00420 s+=intg; 00421 for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1) 00422 { 00423 dec1 x=*--buf; 00424 for (i=min(intg, DIG_PER_DEC1); i; i--) 00425 { 00426 dec1 y=x/10; 00427 *--s='0'+(uchar)(x-y*10); 00428 x=y; 00429 } 00430 } 00431 } 00432 else 00433 *s= '0'; 00434 return error; 00435 }
Here is the call graph for this function:

Definition at line 1027 of file decimal.c.
References buf, DIG_BASE, DIG_PER_DEC1, E_DEC_OK, E_DEC_OVERFLOW, E_DEC_TRUNCATED, from, ULL, ULONGLONG_MAX, unlikely, and x.
01028 { 01029 dec1 *buf=from->buf; 01030 ulonglong x=0; 01031 int intg, frac; 01032 01033 if (from->sign) 01034 { 01035 *to=ULL(0); 01036 return E_DEC_OVERFLOW; 01037 } 01038 01039 for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1) 01040 { 01041 ulonglong y=x; 01042 x=x*DIG_BASE + *buf++; 01043 if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y)) 01044 { 01045 *to=y; 01046 return E_DEC_OVERFLOW; 01047 } 01048 } 01049 *to=x; 01050 for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1) 01051 if (*buf++) 01052 return E_DEC_TRUNCATED; 01053 return E_DEC_OK; 01054 }
| int decimal_actual_fraction | ( | decimal_t * | from | ) |
Definition at line 285 of file decimal.c.
References DIG_PER_DEC1, from, powers10, and ROUND_UP.
00286 { 00287 int frac= from->frac, i; 00288 dec1 *buf0= from->buf + ROUND_UP(from->intg) + ROUND_UP(frac) - 1; 00289 00290 if (frac == 0) 00291 return 0; 00292 00293 i= ((frac - 1) % DIG_PER_DEC1 + 1); 00294 while (frac > 0 && *buf0 == 0) 00295 { 00296 frac-= i; 00297 i= DIG_PER_DEC1; 00298 buf0--; 00299 } 00300 if (frac > 0) 00301 { 00302 for (i= DIG_PER_DEC1 - ((frac - 1) % DIG_PER_DEC1); 00303 *buf0 % powers10[i++] == 0; 00304 frac--); 00305 } 00306 return frac; 00307 }
| int decimal_bin_size | ( | int | precision, | |
| int | scale | |||
| ) |
Definition at line 1431 of file decimal.c.
01432 { 01433 int intg=precision-scale, 01434 intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1, 01435 intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1; 01436 01437 DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision); 01438 return intg0*sizeof(dec1)+dig2bytes[intg0x]+ 01439 frac0*sizeof(dec1)+dig2bytes[frac0x]; 01440 }
Definition at line 2336 of file decimal.c.
References do_div_mod(), and to.
02337 { 02338 return do_div_mod(from1, from2, to, 0, scale_incr); 02339 }
Here is the call graph for this function:

| int decimal_intg | ( | decimal_t * | from | ) |
Definition at line 1899 of file decimal.c.
References from, and remove_leading_zeroes().
01900 { 01901 int res; 01902 dec1 *tmp_res; 01903 tmp_res= remove_leading_zeroes(from, &res); 01904 return res; 01905 }
Here is the call graph for this function:

| int decimal_is_zero | ( | decimal_t * | from | ) |
Definition at line 2368 of file decimal.c.
References do_div_mod(), and to.
02369 { 02370 return do_div_mod(from1, from2, 0, to, 0); 02371 }
Here is the call graph for this function:

Definition at line 1959 of file decimal.c.
References ADD, ADD2, buf, st_decimal_t::buf, bzero, DBUG_ASSERT, decimal_make_zero, DIG_BASE, DIG_PER_DEC1, E_DEC_OVERFLOW, error, FIX_INTG_FRAC_ERROR, st_decimal_t::frac, st_decimal_t::intg, p, ROUND_UP, sanity, set_if_smaller, st_decimal_t::sign, to, and unlikely.
01960 { 01961 int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg), 01962 frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac), 01963 intg0=ROUND_UP(from1->intg+from2->intg), 01964 frac0=frac1+frac2, error, i, j, d_to_move; 01965 dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0, 01966 *start2, *stop2, *stop1, *start0, carry; 01967 01968 sanity(to); 01969 01970 i=intg0; 01971 j=frac0; 01972 FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error); 01973 to->sign=from1->sign != from2->sign; 01974 to->frac=from1->frac+from2->frac; 01975 to->intg=intg0*DIG_PER_DEC1; 01976 01977 if (unlikely(error)) 01978 { 01979 set_if_smaller(to->frac, frac0*DIG_PER_DEC1); 01980 set_if_smaller(to->intg, intg0*DIG_PER_DEC1); 01981 if (unlikely(i > intg0)) 01982 { 01983 i-=intg0; 01984 j=i >> 1; 01985 intg1-= j; 01986 intg2-=i-j; 01987 frac1=frac2=0; /* frac0 is already 0 here */ 01988 } 01989 else 01990 { 01991 j-=frac0; 01992 i=j >> 1; 01993 frac1-= i; 01994 frac2-=j-i; 01995 } 01996 } 01997 start0=to->buf+intg0+frac0-1; 01998 start2=buf2+frac2-1; 01999 stop1=buf1-intg1; 02000 stop2=buf2-intg2; 02001 02002 bzero(to->buf, (intg0+frac0)*sizeof(dec1)); 02003 02004 for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--) 02005 { 02006 carry=0; 02007 for (buf0=start0, buf2=start2; buf2 >= stop2; buf2--, buf0--) 02008 { 02009 dec1 hi, lo; 02010 dec2 p= ((dec2)*buf1) * ((dec2)*buf2); 02011 hi=(dec1)(p/DIG_BASE); 02012 lo=(dec1)(p-((dec2)hi)*DIG_BASE); 02013 ADD2(*buf0, *buf0, lo, carry); 02014 carry+=hi; 02015 } 02016 if (carry) 02017 { 02018 if (buf0 < to->buf) 02019 return E_DEC_OVERFLOW; 02020 ADD2(*buf0, *buf0, 0, carry); 02021 } 02022 for (buf0--; carry; buf0--) 02023 { 02024 if (buf0 < to->buf) 02025 return E_DEC_OVERFLOW; 02026 ADD(*buf0, *buf0, 0, carry); 02027 } 02028 } 02029 02030 /* Now we have to check for -0.000 case */ 02031 if (to->sign) 02032 { 02033 dec1 *buf= to->buf; 02034 dec1 *end= to->buf + intg0 + frac0; 02035 DBUG_ASSERT(buf != end); 02036 for (;;) 02037 { 02038 if (*buf) 02039 break; 02040 if (++buf == end) 02041 { 02042 /* We got decimal zero */ 02043 decimal_make_zero(to); 02044 break; 02045 } 02046 } 02047 } 02048 buf1= to->buf; 02049 d_to_move= intg0 + ROUND_UP(to->frac); 02050 while (!*buf1 && (to->intg > DIG_PER_DEC1)) 02051 { 02052 buf1++; 02053 to->intg-= DIG_PER_DEC1; 02054 d_to_move--; 02055 } 02056 if (to->buf < buf1) 02057 { 02058 dec1 *cur_d= to->buf; 02059 for (; d_to_move--; cur_d++, buf1++) 02060 *cur_d= *buf1; 02061 } 02062 return error; 02063 }
Definition at line 1663 of file decimal.c.
References DBUG_ASSERT, st_decimal_t::frac, st_decimal_t::intg, max, and ROUND_UP.
01664 { 01665 switch (op) { 01666 case '-': 01667 return ROUND_UP(max(from1->intg, from2->intg)) + 01668 ROUND_UP(max(from1->frac, from2->frac)); 01669 case '+': 01670 return ROUND_UP(max(from1->intg, from2->intg)+1) + 01671 ROUND_UP(max(from1->frac, from2->frac)); 01672 case '*': 01673 return ROUND_UP(from1->intg+from2->intg)+ 01674 ROUND_UP(from1->frac)+ROUND_UP(from2->frac); 01675 case '/': 01676 return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param); 01677 default: DBUG_ASSERT(0); 01678 } 01679 return -1; /* shut up the warning */ 01680 }
| int decimal_round | ( | decimal_t * | from, | |
| decimal_t * | to, | |||
| int | new_scale, | |||
| decimal_round_mode | mode | |||
| ) |
Definition at line 1461 of file decimal.c.
References ADD, buf, CEILING, DBUG_ASSERT, decimal_make_zero, DIG_BASE, DIG_MASK, DIG_MAX, DIG_PER_DEC1, E_DEC_OK, E_DEC_TRUNCATED, error, FALSE, FLOOR, from, HALF_EVEN, HALF_UP, likely, max, min, pos(), powers10, ROUND_UP, sanity, to, TRUE, TRUNCATE, unlikely, and x.
01463 { 01464 int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1, 01465 frac1=ROUND_UP(from->frac), round_digit, 01466 intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len, 01467 intg1=ROUND_UP(from->intg + 01468 (((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX))); 01469 dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0; 01470 int first_dig; 01471 01472 sanity(to); 01473 01474 switch (mode) { 01475 case HALF_UP: 01476 case HALF_EVEN: round_digit=5; break; 01477 case CEILING: round_digit= from->sign ? 10 : 0; break; 01478 case FLOOR: round_digit= from->sign ? 0 : 10; break; 01479 case TRUNCATE: round_digit=10; break; 01480 default: DBUG_ASSERT(0); 01481 } 01482 01483 if (unlikely(frac0+intg0 > len)) 01484 { 01485 frac0=len-intg0; 01486 scale=frac0*DIG_PER_DEC1; 01487 error=E_DEC_TRUNCATED; 01488 } 01489 01490 if (scale+from->intg < 0) 01491 { 01492 decimal_make_zero(to); 01493 return E_DEC_OK; 01494 } 01495 01496 if (to != from || intg1>intg0) 01497 { 01498 dec1 *p0= buf0+intg0+max(frac1, frac0); 01499 dec1 *p1= buf1+intg1+max(frac1, frac0); 01500 01501 to->buf[0]= 0; 01502 while (buf0 < p0) 01503 *(--p1) = *(--p0); 01504 01505 intg0= intg1; 01506 buf0=to->buf; 01507 buf1=to->buf; 01508 to->sign=from->sign; 01509 to->intg=min(intg0, len)*DIG_PER_DEC1; 01510 } 01511 01512 if (frac0 > frac1) 01513 { 01514 buf1+=intg0+frac1; 01515 while (frac0-- > frac1) 01516 *buf1++=0; 01517 goto done; 01518 } 01519 01520 if (scale >= from->frac) 01521 goto done; /* nothing to do */ 01522 01523 buf0+=intg0+frac0-1; 01524 buf1+=intg0+frac0-1; 01525 if (scale == frac0*DIG_PER_DEC1) 01526 { 01527 int do_inc= FALSE; 01528 DBUG_ASSERT(frac0+intg0 >= 0); 01529 switch (round_digit) { 01530 case 0: 01531 { 01532 dec1 *p0= buf0 + (frac1-frac0); 01533 for (; p0 > buf0; p0--) 01534 { 01535 if (*p0) 01536 { 01537 do_inc= TRUE; 01538 break; 01539 } 01540 } 01541 break; 01542 } 01543 case 5: 01544 { 01545 x= buf0[1]/DIG_MASK; 01546 do_inc= (x>5) || ((x == 5) && 01547 (mode == HALF_UP || (frac0+intg0 > 0 && *buf0 & 1))); 01548 break; 01549 } 01550 default: 01551 break; 01552 } 01553 if (do_inc) 01554 { 01555 if (frac0+intg0>0) 01556 (*buf1)++; 01557 else 01558 *(++buf1)=DIG_BASE; 01559 } 01560 else if (frac0+intg0==0) 01561 { 01562 decimal_make_zero(to); 01563 return E_DEC_OK; 01564 } 01565 } 01566 else 01567 { 01568 /* TODO - fix this code as it won't work for CEILING mode */ 01569 int pos=frac0*DIG_PER_DEC1-scale-1; 01570 DBUG_ASSERT(frac0+intg0 > 0); 01571 x=*buf1 / powers10[pos]; 01572 y=x % 10; 01573 if (y > round_digit || 01574 (round_digit == 5 && y == 5 && (mode == HALF_UP || (x/10) & 1))) 01575 x+=10; 01576 *buf1=powers10[pos]*(x-y); 01577 } 01578 if (frac0 < 0) 01579 { 01580 dec1 *end=to->buf+intg0, *buf=buf1+1; 01581 while (buf < end) 01582 *buf++=0; 01583 } 01584 if (*buf1 >= DIG_BASE) 01585 { 01586 carry=1; 01587 *buf1-=DIG_BASE; 01588 while (carry && --buf1 >= to->buf) 01589 ADD(*buf1, *buf1, 0, carry); 01590 if (unlikely(carry)) 01591 { 01592 /* shifting the number to create space for new digit */ 01593 if (frac0+intg0 >= len) 01594 { 01595 frac0--; 01596 scale=frac0*DIG_PER_DEC1; 01597 error=E_DEC_TRUNCATED; /* XXX */ 01598 } 01599 for (buf1=to->buf+intg0+max(frac0,0); buf1 > to->buf; buf1--) 01600 { 01601 buf1[0]=buf1[-1]; 01602 } 01603 *buf1=1; 01604 to->intg++; 01605 } 01606 } 01607 else 01608 { 01609 for (;;) 01610 { 01611 if (likely(*buf1)) 01612 break; 01613 if (buf1-- == to->buf) 01614 { 01615 /* making 'zero' with the proper scale */ 01616 dec1 *p0= to->buf + frac0 + 1; 01617 to->intg=1; 01618 to->frac= max(scale, 0); 01619 to->sign= 0; 01620 for (buf1= to->buf; buf1<p0; buf1++) 01621 *buf1= 0; 01622 return E_DEC_OK; 01623 } 01624 } 01625 } 01626 01627 /* Here we check 999.9 -> 1000 case when we need to increase intg */ 01628 first_dig= to->intg % DIG_PER_DEC1; 01629 if (first_dig && (*buf1 >= powers10[first_dig])) 01630 to->intg++; 01631 01632 if (scale<0) 01633 scale=0; 01634 01635 done: 01636 to->frac=scale; 01637 return error; 01638 }
Here is the call graph for this function:

| int decimal_size | ( | int | precision, | |
| int | scale | |||
| ) |
Definition at line 1418 of file decimal.c.
References DBUG_ASSERT, and ROUND_UP.
01419 { 01420 DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision); 01421 return ROUND_UP(precision-scale)+ROUND_UP(scale); 01422 }
| int double2decimal | ( | double | from, | |
| decimal_t * | to | |||
| ) |
Definition at line 973 of file decimal.c.
References DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, my_sprintf, string2decimal, and to.
00974 { 00975 /* TODO: fix it, when we'll have dtoa */ 00976 char buff[400], *end; 00977 int length, res; 00978 DBUG_ENTER("double2decimal"); 00979 length= my_sprintf(buff, (buff, "%.16G", from)); 00980 DBUG_PRINT("info",("from: %g from_as_str: %s", from, buff)); 00981 end= buff+length; 00982 res= string2decimal(buff, to, &end); 00983 DBUG_PRINT("exit", ("res: %d", res)); 00984 DBUG_RETURN(res); 00985 }
Definition at line 790 of file decimal.c.
References buf, decimal_make_zero, decimal_shift(), DIG_PER_DEC1, E_DEC_BAD_NUM, E_DEC_OOM, E_DEC_OVERFLOW, E_DEC_TRUNCATED, error, fatal_error(), FIX_INTG_FRAC_ERROR, int(), my_charset_latin1, my_isdigit, my_isspace, my_strtoll10(), powers10, ROUND_UP, sanity, to, unlikely, and x.
00791 { 00792 const char *s= from, *s1, *endp, *end_of_string= *end; 00793 int i, intg, frac, error, intg1, frac1; 00794 dec1 x,*buf; 00795 sanity(to); 00796 00797 error= E_DEC_BAD_NUM; /* In case of bad number */ 00798 while (s < end_of_string && my_isspace(&my_charset_latin1, *s)) 00799 s++; 00800 if (s == end_of_string) 00801 goto fatal_error; 00802 00803 if ((to->sign= (*s == '-'))) 00804 s++; 00805 else if (*s == '+') 00806 s++; 00807 00808 s1=s; 00809 while (s < end_of_string && my_isdigit(&my_charset_latin1, *s)) 00810 s++; 00811 intg= (int) (s-s1); 00812 if (s < end_of_string && *s=='.') 00813 { 00814 endp= s+1; 00815 while (endp < end_of_string && my_isdigit(&my_charset_latin1, *endp)) 00816 endp++; 00817 frac= (int) (endp - s - 1); 00818 } 00819 else 00820 { 00821 frac= 0; 00822 endp= s; 00823 } 00824 00825 *end= (char*) endp; 00826 00827 if (frac+intg == 0) 00828 goto fatal_error; 00829 00830 error= 0; 00831 if (fixed) 00832 { 00833 if (frac > to->frac) 00834 { 00835 error=E_DEC_TRUNCATED; 00836 frac=to->frac; 00837 } 00838 if (intg > to->intg) 00839 { 00840 error=E_DEC_OVERFLOW; 00841 intg=to->intg; 00842 } 00843 intg1=ROUND_UP(intg); 00844 frac1=ROUND_UP(frac); 00845 if (intg1+frac1 > to->len) 00846 { 00847 error= E_DEC_OOM; 00848 goto fatal_error; 00849 } 00850 } 00851 else 00852 { 00853 intg1=ROUND_UP(intg); 00854 frac1=ROUND_UP(frac); 00855 FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error); 00856 if (unlikely(error)) 00857 { 00858 frac=frac1*DIG_PER_DEC1; 00859 if (error == E_DEC_OVERFLOW) 00860 intg=intg1*DIG_PER_DEC1; 00861 } 00862 } 00863 /* Error is guranteed to be set here */ 00864 to->intg=intg; 00865 to->frac=frac; 00866 00867 buf=to->buf+intg1; 00868 s1=s; 00869 00870 for (x=0, i=0; intg; intg--) 00871 { 00872 x+= (*--s - '0')*powers10[i]; 00873 00874 if (unlikely(++i == DIG_PER_DEC1)) 00875 { 00876 *--buf=x; 00877 x=0; 00878 i=0; 00879 } 00880 } 00881 if (i) 00882 *--buf=x; 00883 00884 buf=to->buf+intg1; 00885 for (x=0, i=0; frac; frac--) 00886 { 00887 x= (*++s1 - '0') + x*10; 00888 00889 if (unlikely(++i == DIG_PER_DEC1)) 00890 { 00891 *buf++=x; 00892 x=0; 00893 i=0; 00894 } 00895 } 00896 if (i) 00897 *buf=x*powers10[DIG_PER_DEC1-i]; 00898 00899 /* Handle exponent */ 00900 if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E')) 00901 { 00902 int str_error; 00903 longlong exp= my_strtoll10(endp+1, (char**) &end_of_string, &str_error); 00904 00905 if (end_of_string != endp +1) /* If at least one digit */ 00906 { 00907 *end= (char*) end_of_string; 00908 if (str_error > 0) 00909 { 00910 error= E_DEC_BAD_NUM; 00911 goto fatal_error; 00912 } 00913 if (exp > INT_MAX/2 || (str_error == 0 && exp < 0)) 00914 { 00915 error= E_DEC_OVERFLOW; 00916 goto fatal_error; 00917 } 00918 if (exp < INT_MIN/2 && error != E_DEC_OVERFLOW) 00919 { 00920 error= E_DEC_TRUNCATED; 00921 goto fatal_error; 00922 } 00923 if (error != E_DEC_OVERFLOW) 00924 error= decimal_shift(to, (int) exp); 00925 } 00926 } 00927 return error; 00928 00929 fatal_error: 00930 decimal_make_zero(to); 00931 return error; 00932 }
Here is the call graph for this function:

| void max_decimal | ( | int | precision, | |
| int | frac, | |||
| decimal_t * | to | |||
| ) |
Definition at line 227 of file decimal.c.
References buf, DBUG_ASSERT, DIG_MAX, DIG_PER_DEC1, frac_max, powers10, and to.
00228 { 00229 int intpart; 00230 dec1 *buf= to->buf; 00231 DBUG_ASSERT(precision && precision >= frac); 00232 00233 to->sign= 0; 00234 if ((intpart= to->intg= (precision - frac))) 00235 { 00236 int firstdigits= intpart % DIG_PER_DEC1; 00237 if (firstdigits) 00238 *buf++= powers10[firstdigits] - 1; /* get 9 99 999 ... */ 00239 for(intpart/= DIG_PER_DEC1; intpart; intpart--) 00240 *buf++= DIG_MAX; 00241 } 00242 00243 if ((to->frac= frac)) 00244 { 00245 int lastdigits= frac % DIG_PER_DEC1; 00246 for(frac/= DIG_PER_DEC1; frac; frac--) 00247 *buf++= DIG_MAX; 00248 if (lastdigits) 00249 *buf= frac_max[lastdigits - 1]; 00250 } 00251 }
1.4.7

