1 /* Copyright (c) 2004, 2015, 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 Without limiting anything contained in the foregoing, this file,
15 which is part of C Driver for MySQL (Connector/C), is also subject to the
16 Universal FOSS Exception, version 1.0, a copy of which can be found at
17 http://oss.oracle.com/licenses/universal-foss-exception.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License, version 2.0, for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
27
28 /*
29 =======================================================================
30 NOTE: this library implements SQL standard "exact numeric" type
31 and is not at all generic, but rather intentinally crippled to
32 follow the standard :)
33 =======================================================================
34 Quoting the standard
35 (SQL:2003, Part 2 Foundations, aka ISO/IEC 9075-2:2003)
36
37 4.4.2 Characteristics of numbers, page 27:
38
39 An exact numeric type has a precision P and a scale S. P is a positive
40 integer that determines the number of significant digits in a
41 particular radix R, where R is either 2 or 10. S is a non-negative
42 integer. Every value of an exact numeric type of scale S is of the
43 form n*10^{-S}, where n is an integer such that �-R^P <= n <= R^P.
44
45 [...]
46
47 If an assignment of some number would result in a loss of its most
48 significant digit, an exception condition is raised. If least
49 significant digits are lost, implementation-defined rounding or
50 truncating occurs, with no exception condition being raised.
51
52 [...]
53
54 Whenever an exact or approximate numeric value is assigned to an exact
55 numeric value site, an approximation of its value that preserves
56 leading significant digits after rounding or truncating is represented
57 in the declared type of the target. The value is converted to have the
58 precision and scale of the target. The choice of whether to truncate
59 or round is implementation-defined.
60
61 [...]
62
63 All numeric values between the smallest and the largest value,
64 inclusive, in a given exact numeric type have an approximation
65 obtained by rounding or truncation for that type; it is
66 implementation-defined which other numeric values have such
67 approximations.
68
69 5.3 <literal>, page 143
70
71 <exact numeric literal> ::=
72 <unsigned integer> [ <period> [ <unsigned integer> ] ]
73 | <period> <unsigned integer>
74
75 6.1 <data type>, page 165:
76
77 19) The <scale> of an <exact numeric type> shall not be greater than
78 the <precision> of the <exact numeric type>.
79
80 20) For the <exact numeric type>s DECIMAL and NUMERIC:
81
82 a) The maximum value of <precision> is implementation-defined.
83 <precision> shall not be greater than this value.
84 b) The maximum value of <scale> is implementation-defined. <scale>
85 shall not be greater than this maximum value.
86
87 21) NUMERIC specifies the data type exact numeric, with the decimal
88 precision and scale specified by the <precision> and <scale>.
89
90 22) DECIMAL specifies the data type exact numeric, with the decimal
91 scale specified by the <scale> and the implementation-defined
92 decimal precision equal to or greater than the value of the
93 specified <precision>.
94
95 6.26 <numeric value expression>, page 241:
96
97 1) If the declared type of both operands of a dyadic arithmetic
98 operator is exact numeric, then the declared type of the result is
99 an implementation-defined exact numeric type, with precision and
100 scale determined as follows:
101
102 a) Let S1 and S2 be the scale of the first and second operands
103 respectively.
104 b) The precision of the result of addition and subtraction is
105 implementation-defined, and the scale is the maximum of S1 and S2.
106 c) The precision of the result of multiplication is
107 implementation-defined, and the scale is S1 + S2.
108 d) The precision and scale of the result of division are
109 implementation-defined.
110 */
111
112 #include <my_global.h>
113 #include <m_ctype.h>
114 #include <myisampack.h>
115 #include <my_sys.h> /* for my_alloca */
116 #include <m_string.h>
117 #include <decimal.h>
118
119 /*
120 Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
121 So one variable of type decimal_digit_t is limited:
122
123 0 < decimal_digit <= DIG_MAX < DIG_BASE
124
125 in the struct st_decimal_t:
126
127 intg is the number of *decimal* digits (NOT number of decimal_digit_t's !)
128 before the point
129 frac - number of decimal digits after the point
130 buf is an array of decimal_digit_t's
131 len is the length of buf (length of allocated space) in decimal_digit_t's,
132 not in bytes
133 */
134 typedef decimal_digit_t dec1;
135 typedef longlong dec2;
136
137 #define DIG_PER_DEC1 9
138 #define DIG_MASK 100000000
139 #define DIG_BASE 1000000000
140 #define DIG_MAX (DIG_BASE-1)
141 #define DIG_BASE2 ((dec2)DIG_BASE * (dec2)DIG_BASE)
142 #define ROUND_UP(X) (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
143 static const dec1 powers10[DIG_PER_DEC1+1]={
144 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
145 static const int dig2bytes[DIG_PER_DEC1+1]={0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
146 static const dec1 frac_max[DIG_PER_DEC1-1]={
147 900000000, 990000000, 999000000,
148 999900000, 999990000, 999999000,
149 999999900, 999999990 };
150
151 #ifdef HAVE_purify
152 #define sanity(d) DBUG_ASSERT((d)->len > 0)
153 #else
154 #define sanity(d) DBUG_ASSERT((d)->len >0 && ((d)->buf[0] | \
155 (d)->buf[(d)->len-1] | 1))
156 #endif
157
158 #define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error) \
159 do \
160 { \
161 if (unlikely(intg1+frac1 > (len))) \
162 { \
163 if (unlikely(intg1 > (len))) \
164 { \
165 intg1=(len); \
166 frac1=0; \
167 error=E_DEC_OVERFLOW; \
168 } \
169 else \
170 { \
171 frac1=(len)-intg1; \
172 error=E_DEC_TRUNCATED; \
173 } \
174 } \
175 else \
176 error=E_DEC_OK; \
177 } while(0)
178
179 #define ADD(to, from1, from2, carry) /* assume carry <= 1 */ \
180 do \
181 { \
182 dec1 a=(from1)+(from2)+(carry); \
183 DBUG_ASSERT((carry) <= 1); \
184 if (((carry)= a >= DIG_BASE)) /* no division here! */ \
185 a-=DIG_BASE; \
186 (to)=a; \
187 } while(0)
188
189 #define ADD2(to, from1, from2, carry) \
190 do \
191 { \
192 dec2 a=((dec2)(from1))+(from2)+(carry); \
193 if (((carry)= a >= DIG_BASE)) \
194 a-=DIG_BASE; \
195 if (unlikely(a >= DIG_BASE)) \
196 { \
197 a-=DIG_BASE; \
198 carry++; \
199 } \
200 (to)=(dec1) a; \
201 } while(0)
202
203 #define SUB(to, from1, from2, carry) /* to=from1-from2 */ \
204 do \
205 { \
206 dec1 a=(from1)-(from2)-(carry); \
207 if (((carry)= a < 0)) \
208 a+=DIG_BASE; \
209 (to)=a; \
210 } while(0)
211
212 #define SUB2(to, from1, from2, carry) /* to=from1-from2 */ \
213 do \
214 { \
215 dec1 a=(from1)-(from2)-(carry); \
216 if (((carry)= a < 0)) \
217 a+=DIG_BASE; \
218 if (unlikely(a < 0)) \
219 { \
220 a+=DIG_BASE; \
221 carry++; \
222 } \
223 (to)=a; \
224 } while(0)
225
226
227 /*
228 This is a direct loop unrolling of code that used to look like this:
229 for (; *buf_beg < powers10[i--]; start++) ;
230
231 @param i start index
232 @param val value to compare against list of powers of 10
233
234 @retval Number of leading zeroes that can be removed from fraction.
235
236 @note Why unroll? To get rid of lots of compiler warnings [-Warray-bounds]
237 Nice bonus: unrolled code is significantly faster.
238 */
count_leading_zeroes(int i,dec1 val)239 static inline int count_leading_zeroes(int i, dec1 val)
240 {
241 int ret= 0;
242 switch (i)
243 {
244 /* @note Intentional fallthrough in all case labels */
245 case 9: if (val >= 1000000000) break; ++ret; // fallthrough
246 case 8: if (val >= 100000000) break; ++ret; // fallthrough
247 case 7: if (val >= 10000000) break; ++ret; // fallthrough
248 case 6: if (val >= 1000000) break; ++ret; // fallthrough
249 case 5: if (val >= 100000) break; ++ret; // fallthrough
250 case 4: if (val >= 10000) break; ++ret; // fallthrough
251 case 3: if (val >= 1000) break; ++ret; // fallthrough
252 case 2: if (val >= 100) break; ++ret; // fallthrough
253 case 1: if (val >= 10) break; ++ret; // fallthrough
254 case 0: if (val >= 1) break; ++ret; // fallthrough
255 default: { DBUG_ASSERT(FALSE); } // fallthrough
256 }
257 return ret;
258 }
259
260 /*
261 This is a direct loop unrolling of code that used to look like this:
262 for (; *buf_end % powers10[i++] == 0; stop--) ;
263
264 @param i start index
265 @param val value to compare against list of powers of 10
266
267 @retval Number of trailing zeroes that can be removed from fraction.
268
269 @note Why unroll? To get rid of lots of compiler warnings [-Warray-bounds]
270 Nice bonus: unrolled code is significantly faster.
271 */
count_trailing_zeroes(int i,dec1 val)272 static inline int count_trailing_zeroes(int i, dec1 val)
273 {
274 int ret= 0;
275 switch(i)
276 {
277 /* @note Intentional fallthrough in all case labels */
278 case 0: if ((val % 1) != 0) break; ++ret; // fallthrough
279 case 1: if ((val % 10) != 0) break; ++ret; // fallthrough
280 case 2: if ((val % 100) != 0) break; ++ret; // fallthrough
281 case 3: if ((val % 1000) != 0) break; ++ret; // fallthrough
282 case 4: if ((val % 10000) != 0) break; ++ret; // fallthrough
283 case 5: if ((val % 100000) != 0) break; ++ret; // fallthrough
284 case 6: if ((val % 1000000) != 0) break; ++ret; // fallthrough
285 case 7: if ((val % 10000000) != 0) break; ++ret; // fallthrough
286 case 8: if ((val % 100000000) != 0) break; ++ret; // fallthrough
287 case 9: if ((val % 1000000000) != 0) break; ++ret; // fallthrough
288 default: { DBUG_ASSERT(FALSE); }
289 }
290 return ret;
291 }
292
293
294 /*
295 Get maximum value for given precision and scale
296
297 SYNOPSIS
298 max_decimal()
299 precision/scale - see decimal_bin_size() below
300 to - decimal where where the result will be stored
301 to->buf and to->len must be set.
302 */
303
max_decimal(int precision,int frac,decimal_t * to)304 void max_decimal(int precision, int frac, decimal_t *to)
305 {
306 int intpart;
307 dec1 *buf= to->buf;
308 DBUG_ASSERT(precision && precision >= frac);
309
310 to->sign= 0;
311 if ((intpart= to->intg= (precision - frac)))
312 {
313 int firstdigits= intpart % DIG_PER_DEC1;
314 if (firstdigits)
315 *buf++= powers10[firstdigits] - 1; /* get 9 99 999 ... */
316 for(intpart/= DIG_PER_DEC1; intpart; intpart--)
317 *buf++= DIG_MAX;
318 }
319
320 if ((to->frac= frac))
321 {
322 int lastdigits= frac % DIG_PER_DEC1;
323 for(frac/= DIG_PER_DEC1; frac; frac--)
324 *buf++= DIG_MAX;
325 if (lastdigits)
326 *buf= frac_max[lastdigits - 1];
327 }
328 }
329
330
remove_leading_zeroes(const decimal_t * from,int * intg_result)331 static dec1 *remove_leading_zeroes(const decimal_t *from, int *intg_result)
332 {
333 int intg= from->intg, i;
334 dec1 *buf0= from->buf;
335 i= ((intg - 1) % DIG_PER_DEC1) + 1;
336 while (intg > 0 && *buf0 == 0)
337 {
338 intg-= i;
339 i= DIG_PER_DEC1;
340 buf0++;
341 }
342 if (intg > 0)
343 {
344 intg-= count_leading_zeroes((intg - 1) % DIG_PER_DEC1, *buf0);
345 DBUG_ASSERT(intg > 0);
346 }
347 else
348 intg=0;
349 *intg_result= intg;
350 return buf0;
351 }
352
353
354 /*
355 Count actual length of fraction part (without ending zeroes)
356
357 SYNOPSIS
358 decimal_actual_fraction()
359 from number for processing
360 */
361
decimal_actual_fraction(decimal_t * from)362 int decimal_actual_fraction(decimal_t *from)
363 {
364 int frac= from->frac, i;
365 dec1 *buf0= from->buf + ROUND_UP(from->intg) + ROUND_UP(frac) - 1;
366
367 if (frac == 0)
368 return 0;
369
370 i= ((frac - 1) % DIG_PER_DEC1 + 1);
371 while (frac > 0 && *buf0 == 0)
372 {
373 frac-= i;
374 i= DIG_PER_DEC1;
375 buf0--;
376 }
377 if (frac > 0)
378 {
379 frac-=
380 count_trailing_zeroes(DIG_PER_DEC1 - ((frac - 1) % DIG_PER_DEC1), *buf0);
381 }
382 return frac;
383 }
384
385
386 /*
387 Convert decimal to its printable string representation
388
389 SYNOPSIS
390 decimal2string()
391 from - value to convert
392 to - points to buffer where string representation
393 should be stored
394 *to_len - in: size of to buffer (incl. terminating '\0')
395 out: length of the actually written string (excl. '\0')
396 fixed_precision - 0 if representation can be variable length and
397 fixed_decimals will not be checked in this case.
398 Put number as with fixed point position with this
399 number of digits (sign counted and decimal point is
400 counted)
401 fixed_decimals - number digits after point.
402 filler - character to fill gaps in case of fixed_precision > 0
403
404 RETURN VALUE
405 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
406 */
407
decimal2string(const decimal_t * from,char * to,int * to_len,int fixed_precision,int fixed_decimals,char filler)408 int decimal2string(const decimal_t *from, char *to, int *to_len,
409 int fixed_precision, int fixed_decimals,
410 char filler)
411 {
412 /* {intg_len, frac_len} output widths; {intg, frac} places in input */
413 int len, intg, frac= from->frac, i, intg_len, frac_len, fill;
414 /* number digits before decimal point */
415 int fixed_intg= (fixed_precision ?
416 (fixed_precision - fixed_decimals) : 0);
417 int error=E_DEC_OK;
418 char *s=to;
419 dec1 *buf, *buf0=from->buf, tmp;
420
421 DBUG_ASSERT(*to_len >= 2+from->sign);
422
423 /* removing leading zeroes */
424 buf0= remove_leading_zeroes(from, &intg);
425 if (unlikely(intg+frac==0))
426 {
427 intg=1;
428 tmp=0;
429 buf0=&tmp;
430 }
431
432 if (!(intg_len= fixed_precision ? fixed_intg : intg))
433 intg_len= 1;
434 frac_len= fixed_precision ? fixed_decimals : frac;
435 len= from->sign + intg_len + MY_TEST(frac) + frac_len;
436 if (fixed_precision)
437 {
438 if (frac > fixed_decimals)
439 {
440 error= E_DEC_TRUNCATED;
441 frac= fixed_decimals;
442 }
443 if (intg > fixed_intg)
444 {
445 error= E_DEC_OVERFLOW;
446 intg= fixed_intg;
447 }
448 }
449 else if (unlikely(len > --*to_len)) /* reserve one byte for \0 */
450 {
451 int j= len - *to_len; /* excess printable chars */
452 error= (frac && j <= frac + 1) ? E_DEC_TRUNCATED : E_DEC_OVERFLOW;
453
454 /*
455 If we need to cut more places than frac is wide, we'll end up
456 dropping the decimal point as well. Account for this.
457 */
458 if (frac && j >= frac + 1)
459 j--;
460
461 if (j > frac)
462 {
463 intg_len= intg-= j-frac;
464 frac= 0;
465 }
466 else
467 frac-=j;
468 frac_len= frac;
469 len= from->sign + intg_len + MY_TEST(frac) + frac_len;
470 }
471 *to_len= len;
472 s[len]= 0;
473
474 if (from->sign)
475 *s++='-';
476
477 if (frac)
478 {
479 char *s1= s + intg_len;
480 fill= frac_len - frac;
481 buf=buf0+ROUND_UP(intg);
482 *s1++='.';
483 for (; frac>0; frac-=DIG_PER_DEC1)
484 {
485 dec1 x=*buf++;
486 for (i= MY_MIN(frac, DIG_PER_DEC1); i; i--)
487 {
488 dec1 y=x/DIG_MASK;
489 *s1++='0'+(uchar)y;
490 x-=y*DIG_MASK;
491 x*=10;
492 }
493 }
494 for(; fill > 0; fill--)
495 *s1++=filler;
496 }
497
498 fill= intg_len - intg;
499 if (intg == 0)
500 fill--; /* symbol 0 before digital point */
501 for(; fill > 0; fill--)
502 *s++=filler;
503 if (intg)
504 {
505 s+=intg;
506 for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
507 {
508 dec1 x=*--buf;
509 for (i= MY_MIN(intg, DIG_PER_DEC1); i; i--)
510 {
511 dec1 y=x/10;
512 *--s='0'+(uchar)(x-y*10);
513 x=y;
514 }
515 }
516 }
517 else
518 *s= '0';
519
520 return error;
521 }
522
523
524 /*
525 Return bounds of decimal digits in the number
526
527 SYNOPSIS
528 digits_bounds()
529 from - decimal number for processing
530 start_result - index (from 0 ) of first decimal digits will
531 be written by this address
532 end_result - index of position just after last decimal digit
533 be written by this address
534 */
535
digits_bounds(decimal_t * from,int * start_result,int * end_result)536 static void digits_bounds(decimal_t *from, int *start_result, int *end_result)
537 {
538 int start, stop, i;
539 dec1 *buf_beg= from->buf;
540 dec1 *end= from->buf + ROUND_UP(from->intg) + ROUND_UP(from->frac);
541 dec1 *buf_end= end - 1;
542
543 /* find non-zero digit from number begining */
544 while (buf_beg < end && *buf_beg == 0)
545 buf_beg++;
546
547 if (buf_beg >= end)
548 {
549 /* it is zero */
550 *start_result= *end_result= 0;
551 return;
552 }
553
554 /* find non-zero decimal digit from number begining */
555 if (buf_beg == from->buf && from->intg)
556 {
557 start= DIG_PER_DEC1 - (i= ((from->intg-1) % DIG_PER_DEC1 + 1));
558 i--;
559 }
560 else
561 {
562 i= DIG_PER_DEC1 - 1;
563 start= (int) ((buf_beg - from->buf) * DIG_PER_DEC1);
564 }
565 if (buf_beg < end)
566 start+= count_leading_zeroes(i, *buf_beg);
567
568 *start_result= start; /* index of first decimal digit (from 0) */
569
570 /* find non-zero digit at the end */
571 while (buf_end > buf_beg && *buf_end == 0)
572 buf_end--;
573 /* find non-zero decimal digit from the end */
574 if (buf_end == end - 1 && from->frac)
575 {
576 stop= (int) (((buf_end - from->buf) * DIG_PER_DEC1 +
577 (i= ((from->frac - 1) % DIG_PER_DEC1 + 1))));
578 i= DIG_PER_DEC1 - i + 1;
579 }
580 else
581 {
582 stop= (int) ((buf_end - from->buf + 1) * DIG_PER_DEC1);
583 i= 1;
584 }
585 stop-= count_trailing_zeroes(i, *buf_end);
586 *end_result= stop; /* index of position after last decimal digit (from 0) */
587 }
588
589
590 /*
591 Left shift for alignment of data in buffer
592
593 SYNOPSIS
594 do_mini_left_shift()
595 dec pointer to decimal number which have to be shifted
596 shift number of decimal digits on which it should be shifted
597 beg/end bounds of decimal digits (see digits_bounds())
598
599 NOTE
600 Result fitting in the buffer should be garanted.
601 'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
602 */
603
do_mini_left_shift(decimal_t * dec,int shift,int beg,int last)604 void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
605 {
606 dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
607 dec1 *end= dec->buf + ROUND_UP(last) - 1;
608 int c_shift= DIG_PER_DEC1 - shift;
609 DBUG_ASSERT(from >= dec->buf);
610 DBUG_ASSERT(end < dec->buf + dec->len);
611 if (beg % DIG_PER_DEC1 < shift)
612 *(from - 1)= (*from) / powers10[c_shift];
613 for(; from < end; from++)
614 *from= ((*from % powers10[c_shift]) * powers10[shift] +
615 (*(from + 1)) / powers10[c_shift]);
616 *from= (*from % powers10[c_shift]) * powers10[shift];
617 }
618
619
620 /*
621 Right shift for alignment of data in buffer
622
623 SYNOPSIS
624 do_mini_left_shift()
625 dec pointer to decimal number which have to be shifted
626 shift number of decimal digits on which it should be shifted
627 beg/end bounds of decimal digits (see digits_bounds())
628
629 NOTE
630 Result fitting in the buffer should be garanted.
631 'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
632 */
633
do_mini_right_shift(decimal_t * dec,int shift,int beg,int last)634 void do_mini_right_shift(decimal_t *dec, int shift, int beg, int last)
635 {
636 dec1 *from= dec->buf + ROUND_UP(last) - 1;
637 dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1;
638 int c_shift= DIG_PER_DEC1 - shift;
639 DBUG_ASSERT(from < dec->buf + dec->len);
640 DBUG_ASSERT(end >= dec->buf);
641 if (DIG_PER_DEC1 - ((last - 1) % DIG_PER_DEC1 + 1) < shift)
642 *(from + 1)= (*from % powers10[shift]) * powers10[c_shift];
643 for(; from > end; from--)
644 *from= (*from / powers10[shift] +
645 (*(from - 1) % powers10[shift]) * powers10[c_shift]);
646 *from= *from / powers10[shift];
647 }
648
649
650 /*
651 Shift of decimal digits in given number (with rounding if it need)
652
653 SYNOPSIS
654 decimal_shift()
655 dec number to be shifted
656 shift number of decimal positions
657 shift > 0 means shift to left shift
658 shift < 0 meand right shift
659 NOTE
660 In fact it is multipling on 10^shift.
661 RETURN
662 E_DEC_OK OK
663 E_DEC_OVERFLOW operation lead to overflow, number is untoched
664 E_DEC_TRUNCATED number was rounded to fit into buffer
665 */
666
decimal_shift(decimal_t * dec,int shift)667 int decimal_shift(decimal_t *dec, int shift)
668 {
669 /* index of first non zero digit (all indexes from 0) */
670 int beg;
671 /* index of position after last decimal digit */
672 int end;
673 /* index of digit position just after point */
674 int point= ROUND_UP(dec->intg) * DIG_PER_DEC1;
675 /* new point position */
676 int new_point= point + shift;
677 /* number of digits in result */
678 int digits_int, digits_frac;
679 /* length of result and new fraction in big digits*/
680 int new_len, new_frac_len;
681 /* return code */
682 int err= E_DEC_OK;
683 int new_front;
684
685 if (shift == 0)
686 return E_DEC_OK;
687
688 digits_bounds(dec, &beg, &end);
689
690 if (beg == end)
691 {
692 decimal_make_zero(dec);
693 return E_DEC_OK;
694 }
695
696 digits_int= new_point - beg;
697 set_if_bigger(digits_int, 0);
698 digits_frac= end - new_point;
699 set_if_bigger(digits_frac, 0);
700
701 if ((new_len= ROUND_UP(digits_int) + (new_frac_len= ROUND_UP(digits_frac))) >
702 dec->len)
703 {
704 int lack= new_len - dec->len;
705 int diff;
706
707 if (new_frac_len < lack)
708 return E_DEC_OVERFLOW; /* lack more then we have in fraction */
709
710 /* cat off fraction part to allow new number to fit in our buffer */
711 err= E_DEC_TRUNCATED;
712 new_frac_len-= lack;
713 diff= digits_frac - (new_frac_len * DIG_PER_DEC1);
714 /* Make rounding method as parameter? */
715 decimal_round(dec, dec, end - point - diff, HALF_UP);
716 end-= diff;
717 digits_frac= new_frac_len * DIG_PER_DEC1;
718
719 if (end <= beg)
720 {
721 /*
722 we lost all digits (they will be shifted out of buffer), so we can
723 just return 0
724 */
725 decimal_make_zero(dec);
726 return E_DEC_TRUNCATED;
727 }
728 }
729
730 if (shift % DIG_PER_DEC1)
731 {
732 int l_mini_shift, r_mini_shift, mini_shift;
733 int do_left;
734 /*
735 Calculate left/right shift to align decimal digits inside our bug
736 digits correctly
737 */
738 if (shift > 0)
739 {
740 l_mini_shift= shift % DIG_PER_DEC1;
741 r_mini_shift= DIG_PER_DEC1 - l_mini_shift;
742 /*
743 It is left shift so prefer left shift, but if we have not place from
744 left, we have to have it from right, because we checked length of
745 result
746 */
747 do_left= l_mini_shift <= beg;
748 DBUG_ASSERT(do_left || (dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
749 }
750 else
751 {
752 r_mini_shift= (-shift) % DIG_PER_DEC1;
753 l_mini_shift= DIG_PER_DEC1 - r_mini_shift;
754 /* see comment above */
755 do_left= !((dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
756 DBUG_ASSERT(!do_left || l_mini_shift <= beg);
757 }
758 if (do_left)
759 {
760 do_mini_left_shift(dec, l_mini_shift, beg, end);
761 mini_shift= -l_mini_shift;
762 }
763 else
764 {
765 do_mini_right_shift(dec, r_mini_shift, beg, end);
766 mini_shift= r_mini_shift;
767 }
768 new_point+= mini_shift;
769 /*
770 If number is shifted and correctly aligned in buffer we can
771 finish
772 */
773 if (!(shift+= mini_shift) && (new_point - digits_int) < DIG_PER_DEC1)
774 {
775 dec->intg= digits_int;
776 dec->frac= digits_frac;
777 return err; /* already shifted as it should be */
778 }
779 beg+= mini_shift;
780 end+= mini_shift;
781 }
782
783 /* if new 'decimal front' is in first digit, we do not need move digits */
784 if ((new_front= (new_point - digits_int)) >= DIG_PER_DEC1 ||
785 new_front < 0)
786 {
787 /* need to move digits */
788 int d_shift;
789 dec1 *to, *barier;
790 if (new_front > 0)
791 {
792 /* move left */
793 d_shift= new_front / DIG_PER_DEC1;
794 to= dec->buf + (ROUND_UP(beg + 1) - 1 - d_shift);
795 barier= dec->buf + (ROUND_UP(end) - 1 - d_shift);
796 DBUG_ASSERT(to >= dec->buf);
797 DBUG_ASSERT(barier + d_shift < dec->buf + dec->len);
798 for(; to <= barier; to++)
799 *to= *(to + d_shift);
800 for(barier+= d_shift; to <= barier; to++)
801 *to= 0;
802 d_shift= -d_shift;
803 }
804 else
805 {
806 /* move right */
807 d_shift= (1 - new_front) / DIG_PER_DEC1;
808 to= dec->buf + ROUND_UP(end) - 1 + d_shift;
809 barier= dec->buf + ROUND_UP(beg + 1) - 1 + d_shift;
810 DBUG_ASSERT(to < dec->buf + dec->len);
811 DBUG_ASSERT(barier - d_shift >= dec->buf);
812 for(; to >= barier; to--)
813 *to= *(to - d_shift);
814 for(barier-= d_shift; to >= barier; to--)
815 *to= 0;
816 }
817 d_shift*= DIG_PER_DEC1;
818 beg+= d_shift;
819 end+= d_shift;
820 new_point+= d_shift;
821 }
822
823 /*
824 If there are gaps then fill ren with 0.
825
826 Only one of following 'for' loops will work becouse beg <= end
827 */
828 beg= ROUND_UP(beg + 1) - 1;
829 end= ROUND_UP(end) - 1;
830 DBUG_ASSERT(new_point >= 0);
831
832 /* We don't want negative new_point below */
833 if (new_point != 0)
834 new_point= ROUND_UP(new_point) - 1;
835
836 if (new_point > end)
837 {
838 do
839 {
840 dec->buf[new_point]=0;
841 } while (--new_point > end);
842 }
843 else
844 {
845 for (; new_point < beg; new_point++)
846 dec->buf[new_point]= 0;
847 }
848 dec->intg= digits_int;
849 dec->frac= digits_frac;
850 return err;
851 }
852
853
854 /*
855 Convert string to decimal
856
857 SYNOPSIS
858 internal_str2decl()
859 from - value to convert. Doesn't have to be \0 terminated!
860 to - decimal where where the result will be stored
861 to->buf and to->len must be set.
862 end - Pointer to pointer to end of string. Will on return be
863 set to the char after the last used character
864 fixed - use to->intg, to->frac as limits for input number
865
866 NOTE
867 to->intg and to->frac can be modified even when fixed=1
868 (but only decreased, in this case)
869
870 RETURN VALUE
871 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_BAD_NUM/E_DEC_OOM
872 In case of E_DEC_FATAL_ERROR *to is set to decimal zero
873 (to make error handling easier)
874 */
875
876 int
internal_str2dec(const char * from,decimal_t * to,char ** end,my_bool fixed)877 internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed)
878 {
879 const char *s= from, *s1, *endp, *end_of_string= *end;
880 int i, intg, frac, error, intg1, frac1;
881 dec1 x,*buf;
882 sanity(to);
883
884 error= E_DEC_BAD_NUM; /* In case of bad number */
885 while (s < end_of_string && my_isspace(&my_charset_latin1, *s))
886 s++;
887 if (s == end_of_string)
888 goto fatal_error;
889
890 if ((to->sign= (*s == '-')))
891 s++;
892 else if (*s == '+')
893 s++;
894
895 s1=s;
896 while (s < end_of_string && my_isdigit(&my_charset_latin1, *s))
897 s++;
898 intg= (int) (s-s1);
899 if (s < end_of_string && *s=='.')
900 {
901 endp= s+1;
902 while (endp < end_of_string && my_isdigit(&my_charset_latin1, *endp))
903 endp++;
904 frac= (int) (endp - s - 1);
905 }
906 else
907 {
908 frac= 0;
909 endp= s;
910 }
911
912 *end= (char*) endp;
913
914 if (frac+intg == 0)
915 goto fatal_error;
916
917 error= 0;
918 if (fixed)
919 {
920 if (frac > to->frac)
921 {
922 error=E_DEC_TRUNCATED;
923 frac=to->frac;
924 }
925 if (intg > to->intg)
926 {
927 error=E_DEC_OVERFLOW;
928 intg=to->intg;
929 }
930 intg1=ROUND_UP(intg);
931 frac1=ROUND_UP(frac);
932 if (intg1+frac1 > to->len)
933 {
934 error= E_DEC_OOM;
935 goto fatal_error;
936 }
937 }
938 else
939 {
940 intg1=ROUND_UP(intg);
941 frac1=ROUND_UP(frac);
942 FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
943 if (unlikely(error))
944 {
945 frac=frac1*DIG_PER_DEC1;
946 if (error == E_DEC_OVERFLOW)
947 intg=intg1*DIG_PER_DEC1;
948 }
949 }
950 /* Error is guranteed to be set here */
951 to->intg=intg;
952 to->frac=frac;
953
954 buf=to->buf+intg1;
955 s1=s;
956
957 for (x=0, i=0; intg; intg--)
958 {
959 x+= (*--s - '0')*powers10[i];
960
961 if (unlikely(++i == DIG_PER_DEC1))
962 {
963 *--buf=x;
964 x=0;
965 i=0;
966 }
967 }
968 if (i)
969 *--buf=x;
970
971 buf=to->buf+intg1;
972 for (x=0, i=0; frac; frac--)
973 {
974 x= (*++s1 - '0') + x*10;
975
976 if (unlikely(++i == DIG_PER_DEC1))
977 {
978 *buf++=x;
979 x=0;
980 i=0;
981 }
982 }
983 if (i)
984 *buf=x*powers10[DIG_PER_DEC1-i];
985
986 /* Handle exponent */
987 if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
988 {
989 int str_error;
990 longlong exponent= my_strtoll10(endp+1, (char**) &end_of_string,
991 &str_error);
992
993 if (end_of_string != endp +1) /* If at least one digit */
994 {
995 *end= (char*) end_of_string;
996 if (str_error > 0)
997 {
998 error= E_DEC_BAD_NUM;
999 goto fatal_error;
1000 }
1001 if (exponent > INT_MAX/2 || (str_error == 0 && exponent < 0))
1002 {
1003 error= E_DEC_OVERFLOW;
1004 goto fatal_error;
1005 }
1006 if (exponent < INT_MIN/2 && error != E_DEC_OVERFLOW)
1007 {
1008 error= E_DEC_TRUNCATED;
1009 goto fatal_error;
1010 }
1011 if (error != E_DEC_OVERFLOW)
1012 error= decimal_shift(to, (int) exponent);
1013 }
1014 }
1015 return error;
1016
1017 fatal_error:
1018 decimal_make_zero(to);
1019 return error;
1020 }
1021
1022
1023 /*
1024 Convert decimal to double
1025
1026 SYNOPSIS
1027 decimal2double()
1028 from - value to convert
1029 to - result will be stored there
1030
1031 RETURN VALUE
1032 E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1033 */
1034
decimal2double(const decimal_t * from,double * to)1035 int decimal2double(const decimal_t *from, double *to)
1036 {
1037 char strbuf[FLOATING_POINT_BUFFER], *end;
1038 int len= sizeof(strbuf);
1039 int rc, error;
1040
1041 rc = decimal2string(from, strbuf, &len, 0, 0, 0);
1042 end= strbuf + len;
1043
1044 DBUG_PRINT("info", ("interm.: %s", strbuf));
1045
1046 *to= my_strtod(strbuf, &end, &error);
1047
1048 DBUG_PRINT("info", ("result: %f", *to));
1049
1050 return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
1051 }
1052
1053 /*
1054 Convert double to decimal
1055
1056 SYNOPSIS
1057 double2decimal()
1058 from - value to convert
1059 to - result will be stored there
1060
1061 RETURN VALUE
1062 E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1063 */
1064
double2decimal(double from,decimal_t * to)1065 int double2decimal(double from, decimal_t *to)
1066 {
1067 char buff[FLOATING_POINT_BUFFER], *end;
1068 int res;
1069 DBUG_ENTER("double2decimal");
1070 end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
1071 res= string2decimal(buff, to, &end);
1072 DBUG_PRINT("exit", ("res: %d", res));
1073 DBUG_RETURN(res);
1074 }
1075
1076
ull2dec(ulonglong from,decimal_t * to)1077 static int ull2dec(ulonglong from, decimal_t *to)
1078 {
1079 int intg1;
1080 int error= E_DEC_OK;
1081 ulonglong x= from;
1082 dec1 *buf;
1083
1084 sanity(to);
1085
1086 if (from == 0)
1087 intg1= 1;
1088 else
1089 {
1090 /* Count the number of decimal_digit_t's we need. */
1091 for (intg1= 0; from != 0; intg1++, from/= DIG_BASE)
1092 ;
1093 }
1094 if (unlikely(intg1 > to->len))
1095 {
1096 intg1= to->len;
1097 error= E_DEC_OVERFLOW;
1098 }
1099 to->frac= 0;
1100 to->intg= intg1 * DIG_PER_DEC1;
1101
1102 for (buf= to->buf + intg1; intg1; intg1--)
1103 {
1104 ulonglong y= x / DIG_BASE;
1105 *--buf=(dec1)(x - y * DIG_BASE);
1106 x= y;
1107 }
1108 return error;
1109 }
1110
ulonglong2decimal(ulonglong from,decimal_t * to)1111 int ulonglong2decimal(ulonglong from, decimal_t *to)
1112 {
1113 to->sign=0;
1114 return ull2dec(from, to);
1115 }
1116
longlong2decimal(longlong from,decimal_t * to)1117 int longlong2decimal(longlong from, decimal_t *to)
1118 {
1119 if ((to->sign= from < 0))
1120 return ull2dec(-from, to);
1121 return ull2dec(from, to);
1122 }
1123
decimal2ulonglong(decimal_t * from,ulonglong * to)1124 int decimal2ulonglong(decimal_t *from, ulonglong *to)
1125 {
1126 dec1 *buf=from->buf;
1127 ulonglong x=0;
1128 int intg, frac;
1129
1130 if (from->sign)
1131 {
1132 *to=ULL(0);
1133 return E_DEC_OVERFLOW;
1134 }
1135
1136 for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1137 {
1138 ulonglong y=x;
1139 x=x*DIG_BASE + *buf++;
1140 if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y))
1141 {
1142 *to=ULONGLONG_MAX;
1143 return E_DEC_OVERFLOW;
1144 }
1145 }
1146 *to=x;
1147 for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1148 if (*buf++)
1149 return E_DEC_TRUNCATED;
1150 return E_DEC_OK;
1151 }
1152
decimal2longlong(decimal_t * from,longlong * to)1153 int decimal2longlong(decimal_t *from, longlong *to)
1154 {
1155 dec1 *buf=from->buf;
1156 longlong x=0;
1157 int intg, frac;
1158
1159 for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1160 {
1161 longlong y=x;
1162 /*
1163 Attention: trick!
1164 we're calculating -|from| instead of |from| here
1165 because |LONGLONG_MIN| > LONGLONG_MAX
1166 so we can convert -9223372036854775808 correctly
1167 */
1168 x=x*DIG_BASE - *buf++;
1169 if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y))
1170 {
1171 /*
1172 the decimal is bigger than any possible integer
1173 return border integer depending on the sign
1174 */
1175 *to= from->sign ? LONGLONG_MIN : LONGLONG_MAX;
1176 return E_DEC_OVERFLOW;
1177 }
1178 }
1179 /* boundary case: 9223372036854775808 */
1180 if (unlikely(from->sign==0 && x == LONGLONG_MIN))
1181 {
1182 *to= LONGLONG_MAX;
1183 return E_DEC_OVERFLOW;
1184 }
1185
1186 *to=from->sign ? x : -x;
1187 for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1188 if (*buf++)
1189 return E_DEC_TRUNCATED;
1190 return E_DEC_OK;
1191 }
1192
1193
1194 #define LLDIV_MIN -1000000000000000000LL
1195 #define LLDIV_MAX 1000000000000000000LL
1196
1197 /**
1198 Convert decimal value to lldiv_t value.
1199 @param from The decimal value to convert from.
1200 @param OUT to The lldiv_t variable to convert to.
1201 @return 0 on success, error code on error.
1202 */
decimal2lldiv_t(const decimal_t * from,lldiv_t * to)1203 int decimal2lldiv_t(const decimal_t *from, lldiv_t *to)
1204 {
1205 int int_part= ROUND_UP(from->intg);
1206 int frac_part= ROUND_UP(from->frac);
1207 if (int_part > 2)
1208 {
1209 to->rem= 0;
1210 to->quot= from->sign ? LLDIV_MIN : LLDIV_MAX;
1211 return E_DEC_OVERFLOW;
1212 }
1213 if (int_part == 2)
1214 to->quot= ((longlong) from->buf[0]) * DIG_BASE + from->buf[1];
1215 else if (int_part == 1)
1216 to->quot= from->buf[0];
1217 else
1218 to->quot= 0;
1219 to->rem= frac_part ? from->buf[int_part] : 0;
1220 if (from->sign)
1221 {
1222 to->quot= -to->quot;
1223 to->rem= -to->rem;
1224 }
1225 return 0;
1226 }
1227
1228
1229 /**
1230 Convert double value to lldiv_t valie.
1231 @param from The double value to convert from.
1232 @param OUT to The lldit_t variable to convert to.
1233 @return 0 on success, error code on error.
1234
1235 Integer part goes into lld.quot.
1236 Fractional part multiplied to 1000000000 (10^9) goes to lld.rem.
1237 Typically used in datetime calculations to split seconds
1238 and nanoseconds.
1239 */
double2lldiv_t(double nr,lldiv_t * lld)1240 int double2lldiv_t(double nr, lldiv_t *lld)
1241 {
1242 if (nr > LLDIV_MAX)
1243 {
1244 lld->quot= LLDIV_MAX;
1245 lld->rem= 0;
1246 return E_DEC_OVERFLOW;
1247 }
1248 else if (nr < LLDIV_MIN)
1249 {
1250 lld->quot= LLDIV_MIN;
1251 lld->rem= 0;
1252 return E_DEC_OVERFLOW;
1253 }
1254 /* Truncate fractional part toward zero and store into "quot" */
1255 lld->quot= (longlong) (nr > 0 ? floor(nr) : ceil(nr));
1256 /* Multiply reminder to 10^9 and store into "rem" */
1257 lld->rem= (longlong) rint((nr - (double) lld->quot) * 1000000000);
1258 /*
1259 Sometimes the expression "(double) 0.999999999xxx * (double) 10e9"
1260 gives 1,000,000,000 instead of 999,999,999 due to lack of double precision.
1261 The callers do not expect lld->rem to be greater than 999,999,999.
1262 Let's catch this corner case and put the "nanounit" (e.g. nanosecond)
1263 value in ldd->rem back into the valid range.
1264 */
1265 if (lld->rem > 999999999LL)
1266 lld->rem= 999999999LL;
1267 else if (lld->rem < -999999999LL)
1268 lld->rem= -999999999LL;
1269 return E_DEC_OK;
1270 }
1271
1272
1273
1274 /*
1275 Convert decimal to its binary fixed-length representation
1276 two representations of the same length can be compared with memcmp
1277 with the correct -1/0/+1 result
1278
1279 SYNOPSIS
1280 decimal2bin()
1281 from - value to convert
1282 to - points to buffer where string representation should be stored
1283 precision/scale - see decimal_bin_size() below
1284
1285 NOTE
1286 the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1287
1288 RETURN VALUE
1289 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1290
1291 DESCRIPTION
1292 for storage decimal numbers are converted to the "binary" format.
1293
1294 This format has the following properties:
1295 1. length of the binary representation depends on the {precision, scale}
1296 as provided by the caller and NOT on the intg/frac of the decimal to
1297 convert.
1298 2. binary representations of the same {precision, scale} can be compared
1299 with memcmp - with the same result as decimal_cmp() of the original
1300 decimals (not taking into account possible precision loss during
1301 conversion).
1302
1303 This binary format is as follows:
1304 1. First the number is converted to have a requested precision and scale.
1305 2. Every full DIG_PER_DEC1 digits of intg part are stored in 4 bytes
1306 as is
1307 3. The first intg % DIG_PER_DEC1 digits are stored in the reduced
1308 number of bytes (enough bytes to store this number of digits -
1309 see dig2bytes)
1310 4. same for frac - full decimal_digit_t's are stored as is,
1311 the last frac % DIG_PER_DEC1 digits - in the reduced number of bytes.
1312 5. If the number is negative - every byte is inversed.
1313 5. The very first bit of the resulting byte array is inverted (because
1314 memcmp compares unsigned bytes, see property 2 above)
1315
1316 Example:
1317
1318 1234567890.1234
1319
1320 internally is represented as 3 decimal_digit_t's
1321
1322 1 234567890 123400000
1323
1324 (assuming we want a binary representation with precision=14, scale=4)
1325 in hex it's
1326
1327 00-00-00-01 0D-FB-38-D2 07-5A-EF-40
1328
1329 now, middle decimal_digit_t is full - it stores 9 decimal digits. It goes
1330 into binary representation as is:
1331
1332
1333 ........... 0D-FB-38-D2 ............
1334
1335 First decimal_digit_t has only one decimal digit. We can store one digit in
1336 one byte, no need to waste four:
1337
1338 01 0D-FB-38-D2 ............
1339
1340 now, last digit. It's 123400000. We can store 1234 in two bytes:
1341
1342 01 0D-FB-38-D2 04-D2
1343
1344 So, we've packed 12 bytes number in 7 bytes.
1345 And now we invert the highest bit to get the final result:
1346
1347 81 0D FB 38 D2 04 D2
1348
1349 And for -1234567890.1234 it would be
1350
1351 7E F2 04 C7 2D FB 2D
1352 */
decimal2bin(decimal_t * from,uchar * to,int precision,int frac)1353 int decimal2bin(decimal_t *from, uchar *to, int precision, int frac)
1354 {
1355 dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1356 int error=E_DEC_OK, intg=precision-frac,
1357 isize1, intg1, intg1x, from_intg,
1358 intg0=intg/DIG_PER_DEC1,
1359 frac0=frac/DIG_PER_DEC1,
1360 intg0x=intg-intg0*DIG_PER_DEC1,
1361 frac0x=frac-frac0*DIG_PER_DEC1,
1362 frac1=from->frac/DIG_PER_DEC1,
1363 frac1x=from->frac-frac1*DIG_PER_DEC1,
1364 isize0=intg0*sizeof(dec1)+dig2bytes[intg0x],
1365 fsize0=frac0*sizeof(dec1)+dig2bytes[frac0x],
1366 fsize1=frac1*sizeof(dec1)+dig2bytes[frac1x];
1367 const int orig_isize0= isize0;
1368 const int orig_fsize0= fsize0;
1369 uchar *orig_to= to;
1370
1371 buf1= remove_leading_zeroes(from, &from_intg);
1372
1373 if (unlikely(from_intg+fsize1==0))
1374 {
1375 mask=0; /* just in case */
1376 intg=1;
1377 buf1=&mask;
1378 }
1379
1380 intg1=from_intg/DIG_PER_DEC1;
1381 intg1x=from_intg-intg1*DIG_PER_DEC1;
1382 isize1=intg1*sizeof(dec1)+dig2bytes[intg1x];
1383
1384 if (intg < from_intg)
1385 {
1386 buf1+=intg1-intg0+(intg1x>0)-(intg0x>0);
1387 intg1=intg0; intg1x=intg0x;
1388 error=E_DEC_OVERFLOW;
1389 }
1390 else if (isize0 > isize1)
1391 {
1392 while (isize0-- > isize1)
1393 *to++= (char)mask;
1394 }
1395 if (fsize0 < fsize1)
1396 {
1397 frac1=frac0; frac1x=frac0x;
1398 error=E_DEC_TRUNCATED;
1399 }
1400 else if (fsize0 > fsize1 && frac1x)
1401 {
1402 if (frac0 == frac1)
1403 {
1404 frac1x=frac0x;
1405 fsize0= fsize1;
1406 }
1407 else
1408 {
1409 frac1++;
1410 frac1x=0;
1411 }
1412 }
1413
1414 /* intg1x part */
1415 if (intg1x)
1416 {
1417 int i=dig2bytes[intg1x];
1418 dec1 x=(*buf1++ % powers10[intg1x]) ^ mask;
1419 switch (i)
1420 {
1421 case 1: mi_int1store(to, x); break;
1422 case 2: mi_int2store(to, x); break;
1423 case 3: mi_int3store(to, x); break;
1424 case 4: mi_int4store(to, x); break;
1425 default: DBUG_ASSERT(0);
1426 }
1427 to+=i;
1428 }
1429
1430 /* intg1+frac1 part */
1431 for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=sizeof(dec1))
1432 {
1433 dec1 x=*buf1++ ^ mask;
1434 DBUG_ASSERT(sizeof(dec1) == 4);
1435 mi_int4store(to, x);
1436 }
1437
1438 /* frac1x part */
1439 if (frac1x)
1440 {
1441 dec1 x;
1442 int i=dig2bytes[frac1x],
1443 lim=(frac1 < frac0 ? DIG_PER_DEC1 : frac0x);
1444 while (frac1x < lim && dig2bytes[frac1x] == i)
1445 frac1x++;
1446 x=(*buf1 / powers10[DIG_PER_DEC1 - frac1x]) ^ mask;
1447 switch (i)
1448 {
1449 case 1: mi_int1store(to, x); break;
1450 case 2: mi_int2store(to, x); break;
1451 case 3: mi_int3store(to, x); break;
1452 case 4: mi_int4store(to, x); break;
1453 default: DBUG_ASSERT(0);
1454 }
1455 to+=i;
1456 }
1457 if (fsize0 > fsize1)
1458 {
1459 uchar *to_end= orig_to + orig_fsize0 + orig_isize0;
1460
1461 while (fsize0-- > fsize1 && to < to_end)
1462 *to++= (uchar)mask;
1463 }
1464 orig_to[0]^= 0x80;
1465
1466 /* Check that we have written the whole decimal and nothing more */
1467 DBUG_ASSERT(to == orig_to + orig_fsize0 + orig_isize0);
1468 return error;
1469 }
1470
1471 /*
1472 Restores decimal from its binary fixed-length representation
1473
1474 SYNOPSIS
1475 bin2decimal()
1476 from - value to convert
1477 to - result
1478 precision/scale - see decimal_bin_size() below
1479
1480 NOTE
1481 see decimal2bin()
1482 the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1483
1484 RETURN VALUE
1485 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1486 */
1487
bin2decimal(const uchar * from,decimal_t * to,int precision,int scale)1488 int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale)
1489 {
1490 int error=E_DEC_OK, intg=precision-scale,
1491 intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1492 intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
1493 intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
1494 dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
1495 const uchar *stop;
1496 uchar *d_copy;
1497 int bin_size= decimal_bin_size(precision, scale);
1498
1499 sanity(to);
1500 d_copy= (uchar*) my_alloca(bin_size);
1501 memcpy(d_copy, from, bin_size);
1502 d_copy[0]^= 0x80;
1503 from= d_copy;
1504
1505 FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
1506 if (unlikely(error))
1507 {
1508 if (intg1 < intg0+(intg0x>0))
1509 {
1510 from+=dig2bytes[intg0x]+sizeof(dec1)*(intg0-intg1);
1511 frac0=frac0x=intg0x=0;
1512 intg0=intg1;
1513 }
1514 else
1515 {
1516 frac0x=0;
1517 frac0=frac1;
1518 }
1519 }
1520
1521 to->sign=(mask != 0);
1522 to->intg=intg0*DIG_PER_DEC1+intg0x;
1523 to->frac=frac0*DIG_PER_DEC1+frac0x;
1524
1525 if (intg0x)
1526 {
1527 int i=dig2bytes[intg0x];
1528 dec1 UNINIT_VAR(x);
1529 switch (i)
1530 {
1531 case 1: x=mi_sint1korr(from); break;
1532 case 2: x=mi_sint2korr(from); break;
1533 case 3: x=mi_sint3korr(from); break;
1534 case 4: x=mi_sint4korr(from); break;
1535 default: DBUG_ASSERT(0);
1536 }
1537 from+=i;
1538 *buf=x ^ mask;
1539 if (((ulonglong)*buf) >= (ulonglong) powers10[intg0x+1])
1540 goto err;
1541 if (buf > to->buf || *buf != 0)
1542 buf++;
1543 else
1544 to->intg-=intg0x;
1545 }
1546 for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1547 {
1548 DBUG_ASSERT(sizeof(dec1) == 4);
1549 *buf=mi_sint4korr(from) ^ mask;
1550 if (((uint32)*buf) > DIG_MAX)
1551 goto err;
1552 if (buf > to->buf || *buf != 0)
1553 buf++;
1554 else
1555 to->intg-=DIG_PER_DEC1;
1556 }
1557 DBUG_ASSERT(to->intg >=0);
1558 for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1559 {
1560 DBUG_ASSERT(sizeof(dec1) == 4);
1561 *buf=mi_sint4korr(from) ^ mask;
1562 if (((uint32)*buf) > DIG_MAX)
1563 goto err;
1564 buf++;
1565 }
1566 if (frac0x)
1567 {
1568 int i=dig2bytes[frac0x];
1569 dec1 UNINIT_VAR(x);
1570 switch (i)
1571 {
1572 case 1: x=mi_sint1korr(from); break;
1573 case 2: x=mi_sint2korr(from); break;
1574 case 3: x=mi_sint3korr(from); break;
1575 case 4: x=mi_sint4korr(from); break;
1576 default: DBUG_ASSERT(0);
1577 }
1578 *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
1579 if (((uint32)*buf) > DIG_MAX)
1580 goto err;
1581 buf++;
1582 }
1583 my_afree(d_copy);
1584
1585 /*
1586 No digits? We have read the number zero, of unspecified precision.
1587 Make it a proper zero, with non-zero precision.
1588 */
1589 if (to->intg == 0 && to->frac == 0)
1590 decimal_make_zero(to);
1591 return error;
1592
1593 err:
1594 my_afree(d_copy);
1595 decimal_make_zero(to);
1596 return(E_DEC_BAD_NUM);
1597 }
1598
1599 /*
1600 Returns the size of array to hold a decimal with given precision and scale
1601
1602 RETURN VALUE
1603 size in dec1
1604 (multiply by sizeof(dec1) to get the size if bytes)
1605 */
1606
decimal_size(int precision,int scale)1607 int decimal_size(int precision, int scale)
1608 {
1609 DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
1610 return ROUND_UP(precision-scale)+ROUND_UP(scale);
1611 }
1612
1613 /*
1614 Returns the size of array to hold a binary representation of a decimal
1615
1616 RETURN VALUE
1617 size in bytes
1618 */
1619
decimal_bin_size(int precision,int scale)1620 int decimal_bin_size(int precision, int scale)
1621 {
1622 int intg=precision-scale,
1623 intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1624 intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1;
1625
1626 DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
1627 return intg0*sizeof(dec1)+dig2bytes[intg0x]+
1628 frac0*sizeof(dec1)+dig2bytes[frac0x];
1629 }
1630
1631 /*
1632 Rounds the decimal to "scale" digits
1633
1634 SYNOPSIS
1635 decimal_round()
1636 from - decimal to round,
1637 to - result buffer. from==to is allowed
1638 scale - to what position to round. can be negative!
1639 mode - round to nearest even or truncate
1640
1641 NOTES
1642 scale can be negative !
1643 one TRUNCATED error (line XXX below) isn't treated very logical :(
1644
1645 RETURN VALUE
1646 E_DEC_OK/E_DEC_TRUNCATED
1647 */
1648
1649 int
decimal_round(const decimal_t * from,decimal_t * to,int scale,decimal_round_mode mode)1650 decimal_round(const decimal_t *from, decimal_t *to, int scale,
1651 decimal_round_mode mode)
1652 {
1653 int frac0=scale>0 ? ROUND_UP(scale) : (scale + 1)/DIG_PER_DEC1,
1654 frac1=ROUND_UP(from->frac), UNINIT_VAR(round_digit),
1655 intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len;
1656
1657 dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
1658 int first_dig;
1659
1660 sanity(to);
1661
1662 switch (mode) {
1663 case HALF_UP:
1664 case HALF_EVEN: round_digit=5; break;
1665 case CEILING: round_digit= from->sign ? 10 : 0; break;
1666 case FLOOR: round_digit= from->sign ? 0 : 10; break;
1667 case TRUNCATE: round_digit=10; break;
1668 default: DBUG_ASSERT(0);
1669 }
1670
1671 /*
1672 For my_decimal we always use len == DECIMAL_BUFF_LENGTH == 9
1673 For internal testing here (ifdef MAIN) we always use len == 100/4
1674 */
1675 DBUG_ASSERT(from->len == to->len);
1676
1677 if (unlikely(frac0+intg0 > len))
1678 {
1679 frac0=len-intg0;
1680 scale=frac0*DIG_PER_DEC1;
1681 error=E_DEC_TRUNCATED;
1682 }
1683
1684 if (scale+from->intg < 0)
1685 {
1686 decimal_make_zero(to);
1687 return E_DEC_OK;
1688 }
1689
1690 if (to != from)
1691 {
1692 dec1 *p0= buf0 + intg0 + MY_MAX(frac1, frac0);
1693 dec1 *p1= buf1 + intg0 + MY_MAX(frac1, frac0);
1694
1695 DBUG_ASSERT(p0 - buf0 <= len);
1696 DBUG_ASSERT(p1 - buf1 <= len);
1697
1698 while (buf0 < p0)
1699 *(--p1) = *(--p0);
1700
1701 buf0=to->buf;
1702 buf1=to->buf;
1703 to->sign=from->sign;
1704 to->intg= MY_MIN(intg0, len) * DIG_PER_DEC1;
1705 }
1706
1707 if (frac0 > frac1)
1708 {
1709 buf1+=intg0+frac1;
1710 while (frac0-- > frac1)
1711 *buf1++=0;
1712 goto done;
1713 }
1714
1715 if (scale >= from->frac)
1716 goto done; /* nothing to do */
1717
1718 buf0+=intg0+frac0-1;
1719 buf1+=intg0+frac0-1;
1720 if (scale == frac0*DIG_PER_DEC1)
1721 {
1722 int do_inc= FALSE;
1723 DBUG_ASSERT(frac0+intg0 >= 0);
1724 switch (round_digit) {
1725 case 0:
1726 {
1727 dec1 *p0= buf0 + (frac1-frac0);
1728 for (; p0 > buf0; p0--)
1729 {
1730 if (*p0)
1731 {
1732 do_inc= TRUE;
1733 break;
1734 }
1735 }
1736 break;
1737 }
1738 case 5:
1739 {
1740 x= buf0[1]/DIG_MASK;
1741 do_inc= (x>5) || ((x == 5) &&
1742 (mode == HALF_UP || (frac0+intg0 > 0 && *buf0 & 1)));
1743 break;
1744 }
1745 default:
1746 break;
1747 }
1748 if (do_inc)
1749 {
1750 if (frac0+intg0>0)
1751 (*buf1)++;
1752 else
1753 *(++buf1)=DIG_BASE;
1754 }
1755 else if (frac0+intg0==0)
1756 {
1757 decimal_make_zero(to);
1758 return E_DEC_OK;
1759 }
1760 }
1761 else
1762 {
1763 /* TODO - fix this code as it won't work for CEILING mode */
1764 int pos=frac0*DIG_PER_DEC1-scale-1;
1765 DBUG_ASSERT(frac0+intg0 > 0);
1766 x=*buf1 / powers10[pos];
1767 y=x % 10;
1768 if (y > round_digit ||
1769 (round_digit == 5 && y == 5 && (mode == HALF_UP || (x/10) & 1)))
1770 x+=10;
1771 *buf1=powers10[pos]*(x-y);
1772 }
1773 /*
1774 In case we're rounding e.g. 1.5e9 to 2.0e9, the decimal_digit_t's inside
1775 the buffer are as follows.
1776
1777 Before <1, 5e8>
1778 After <2, 5e8>
1779
1780 Hence we need to set the 2nd field to 0.
1781 The same holds if we round 1.5e-9 to 2e-9.
1782 */
1783 if (frac0 < frac1)
1784 {
1785 dec1 *buf= to->buf + ((scale == 0 && intg0 == 0) ? 1 : intg0 + frac0);
1786 dec1 *end= to->buf + len;
1787
1788 while (buf < end)
1789 *buf++=0;
1790 }
1791 if (*buf1 >= DIG_BASE)
1792 {
1793 carry=1;
1794 *buf1-=DIG_BASE;
1795 while (carry && --buf1 >= to->buf)
1796 ADD(*buf1, *buf1, 0, carry);
1797 if (unlikely(carry))
1798 {
1799 /* shifting the number to create space for new digit */
1800 if (frac0+intg0 >= len)
1801 {
1802 frac0--;
1803 scale=frac0*DIG_PER_DEC1;
1804 error=E_DEC_TRUNCATED; /* XXX */
1805 }
1806 for (buf1=to->buf + intg0 + MY_MAX(frac0, 0); buf1 > to->buf; buf1--)
1807 {
1808 /* Avoid out-of-bounds write. */
1809 if (buf1 < to->buf + len)
1810 buf1[0]=buf1[-1];
1811 else
1812 error= E_DEC_OVERFLOW;
1813 }
1814 *buf1=1;
1815 /* We cannot have more than 9 * 9 = 81 digits. */
1816 if (to->intg < len * DIG_PER_DEC1)
1817 to->intg++;
1818 else
1819 error= E_DEC_OVERFLOW;
1820 }
1821 }
1822 else
1823 {
1824 for (;;)
1825 {
1826 if (likely(*buf1))
1827 break;
1828 if (buf1-- == to->buf)
1829 {
1830 /* making 'zero' with the proper scale */
1831 dec1 *p0= to->buf + frac0 + 1;
1832 to->intg=1;
1833 to->frac= MY_MAX(scale, 0);
1834 to->sign= 0;
1835 for (buf1= to->buf; buf1<p0; buf1++)
1836 *buf1= 0;
1837 return E_DEC_OK;
1838 }
1839 }
1840 }
1841
1842 /* Here we check 999.9 -> 1000 case when we need to increase intg */
1843 first_dig= to->intg % DIG_PER_DEC1;
1844 if (first_dig && (*buf1 >= powers10[first_dig]))
1845 to->intg++;
1846
1847 if (scale<0)
1848 scale=0;
1849
1850 done:
1851 DBUG_ASSERT(to->intg <= (len * DIG_PER_DEC1));
1852 to->frac=scale;
1853 return error;
1854 }
1855
1856 /*
1857 Returns the size of the result of the operation
1858
1859 SYNOPSIS
1860 decimal_result_size()
1861 from1 - operand of the unary operation or first operand of the
1862 binary operation
1863 from2 - second operand of the binary operation
1864 op - operation. one char '+', '-', '*', '/' are allowed
1865 others may be added later
1866 param - extra param to the operation. unused for '+', '-', '*'
1867 scale increment for '/'
1868
1869 NOTE
1870 returned valued may be larger than the actual buffer requred
1871 in the operation, as decimal_result_size, by design, operates on
1872 precision/scale values only and not on the actual decimal number
1873
1874 RETURN VALUE
1875 size of to->buf array in dec1 elements. to get size in bytes
1876 multiply by sizeof(dec1)
1877 */
1878
decimal_result_size(decimal_t * from1,decimal_t * from2,char op,int param)1879 int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param)
1880 {
1881 switch (op) {
1882 case '-':
1883 return ROUND_UP(MY_MAX(from1->intg, from2->intg)) +
1884 ROUND_UP(MY_MAX(from1->frac, from2->frac));
1885 case '+':
1886 return ROUND_UP(MY_MAX(from1->intg, from2->intg)+1) +
1887 ROUND_UP(MY_MAX(from1->frac, from2->frac));
1888 case '*':
1889 return ROUND_UP(from1->intg+from2->intg)+
1890 ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
1891 case '/':
1892 return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param);
1893 default: DBUG_ASSERT(0);
1894 }
1895 return -1; /* shut up the warning */
1896 }
1897
do_add(const decimal_t * from1,const decimal_t * from2,decimal_t * to)1898 static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1899 {
1900 int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1901 frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1902 frac0= MY_MAX(frac1, frac2), intg0= MY_MAX(intg1, intg2), error;
1903 dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
1904
1905 sanity(to);
1906
1907 /* is there a need for extra word because of carry ? */
1908 x=intg1 > intg2 ? from1->buf[0] :
1909 intg2 > intg1 ? from2->buf[0] :
1910 from1->buf[0] + from2->buf[0] ;
1911 if (unlikely(x > DIG_MAX-1)) /* yes, there is */
1912 {
1913 intg0++;
1914 to->buf[0]=0; /* safety */
1915 }
1916
1917 FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
1918 if (unlikely(error == E_DEC_OVERFLOW))
1919 {
1920 max_decimal(to->len * DIG_PER_DEC1, 0, to);
1921 return error;
1922 }
1923
1924 buf0=to->buf+intg0+frac0;
1925
1926 to->sign=from1->sign;
1927 to->frac= MY_MAX(from1->frac, from2->frac);
1928 to->intg=intg0*DIG_PER_DEC1;
1929 if (unlikely(error))
1930 {
1931 set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
1932 set_if_smaller(frac1, frac0);
1933 set_if_smaller(frac2, frac0);
1934 set_if_smaller(intg1, intg0);
1935 set_if_smaller(intg2, intg0);
1936 }
1937
1938 /* part 1 - max(frac) ... min (frac) */
1939 if (frac1 > frac2)
1940 {
1941 buf1=from1->buf+intg1+frac1;
1942 stop=from1->buf+intg1+frac2;
1943 buf2=from2->buf+intg2+frac2;
1944 stop2=from1->buf+(intg1 > intg2 ? intg1-intg2 : 0);
1945 }
1946 else
1947 {
1948 buf1=from2->buf+intg2+frac2;
1949 stop=from2->buf+intg2+frac1;
1950 buf2=from1->buf+intg1+frac1;
1951 stop2=from2->buf+(intg2 > intg1 ? intg2-intg1 : 0);
1952 }
1953 while (buf1 > stop)
1954 *--buf0=*--buf1;
1955
1956 /* part 2 - min(frac) ... min(intg) */
1957 carry=0;
1958 while (buf1 > stop2)
1959 {
1960 ADD(*--buf0, *--buf1, *--buf2, carry);
1961 }
1962
1963 /* part 3 - min(intg) ... max(intg) */
1964 buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
1965 ((stop=from2->buf)+intg2-intg1) ;
1966 while (buf1 > stop)
1967 {
1968 ADD(*--buf0, *--buf1, 0, carry);
1969 }
1970
1971 if (unlikely(carry))
1972 *--buf0=1;
1973 DBUG_ASSERT(buf0 == to->buf || buf0 == to->buf+1);
1974
1975 return error;
1976 }
1977
1978 /* to=from1-from2.
1979 if to==0, return -1/0/+1 - the result of the comparison */
do_sub(const decimal_t * from1,const decimal_t * from2,decimal_t * to)1980 static int do_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1981 {
1982 int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1983 frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
1984 int frac0= MY_MAX(frac1, frac2), error;
1985 dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
1986
1987 /* let carry:=1 if from2 > from1 */
1988 start1=buf1=from1->buf; stop1=buf1+intg1;
1989 start2=buf2=from2->buf; stop2=buf2+intg2;
1990 if (unlikely(*buf1 == 0))
1991 {
1992 while (buf1 < stop1 && *buf1 == 0)
1993 buf1++;
1994 start1=buf1;
1995 intg1= (int) (stop1-buf1);
1996 }
1997 if (unlikely(*buf2 == 0))
1998 {
1999 while (buf2 < stop2 && *buf2 == 0)
2000 buf2++;
2001 start2=buf2;
2002 intg2= (int) (stop2-buf2);
2003 }
2004 if (intg2 > intg1)
2005 carry=1;
2006 else if (intg2 == intg1)
2007 {
2008 dec1 *end1= stop1 + (frac1 - 1);
2009 dec1 *end2= stop2 + (frac2 - 1);
2010 while (unlikely((buf1 <= end1) && (*end1 == 0)))
2011 end1--;
2012 while (unlikely((buf2 <= end2) && (*end2 == 0)))
2013 end2--;
2014 frac1= (int) (end1 - stop1) + 1;
2015 frac2= (int) (end2 - stop2) + 1;
2016 while (buf1 <=end1 && buf2 <= end2 && *buf1 == *buf2)
2017 buf1++, buf2++;
2018 if (buf1 <= end1)
2019 {
2020 if (buf2 <= end2)
2021 carry= *buf2 > *buf1;
2022 else
2023 carry= 0;
2024 }
2025 else
2026 {
2027 if (buf2 <= end2)
2028 carry=1;
2029 else /* short-circuit everything: from1 == from2 */
2030 {
2031 if (to == 0) /* decimal_cmp() */
2032 return 0;
2033 decimal_make_zero(to);
2034 return E_DEC_OK;
2035 }
2036 }
2037 }
2038
2039 if (to == 0) /* decimal_cmp() */
2040 return carry == from1->sign ? 1 : -1;
2041
2042 sanity(to);
2043
2044 to->sign=from1->sign;
2045
2046 /* ensure that always from1 > from2 (and intg1 >= intg2) */
2047 if (carry)
2048 {
2049 swap_variables(const decimal_t *, from1, from2);
2050 swap_variables(dec1 *,start1, start2);
2051 swap_variables(int,intg1,intg2);
2052 swap_variables(int,frac1,frac2);
2053 to->sign= 1 - to->sign;
2054 }
2055
2056 FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
2057 buf0=to->buf+intg1+frac0;
2058
2059 to->frac= MY_MAX(from1->frac, from2->frac);
2060 to->intg=intg1*DIG_PER_DEC1;
2061 if (unlikely(error))
2062 {
2063 set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
2064 set_if_smaller(frac1, frac0);
2065 set_if_smaller(frac2, frac0);
2066 set_if_smaller(intg2, intg1);
2067 }
2068 carry=0;
2069
2070 /* part 1 - max(frac) ... min (frac) */
2071 if (frac1 > frac2)
2072 {
2073 buf1=start1+intg1+frac1;
2074 stop1=start1+intg1+frac2;
2075 buf2=start2+intg2+frac2;
2076 while (frac0-- > frac1)
2077 *--buf0=0;
2078 while (buf1 > stop1)
2079 *--buf0=*--buf1;
2080 }
2081 else
2082 {
2083 buf1=start1+intg1+frac1;
2084 buf2=start2+intg2+frac2;
2085 stop2=start2+intg2+frac1;
2086 while (frac0-- > frac2)
2087 *--buf0=0;
2088 while (buf2 > stop2)
2089 {
2090 SUB(*--buf0, 0, *--buf2, carry);
2091 }
2092 }
2093
2094 /* part 2 - min(frac) ... intg2 */
2095 while (buf2 > start2)
2096 {
2097 SUB(*--buf0, *--buf1, *--buf2, carry);
2098 }
2099
2100 /* part 3 - intg2 ... intg1 */
2101 while (carry && buf1 > start1)
2102 {
2103 SUB(*--buf0, *--buf1, 0, carry);
2104 }
2105
2106 while (buf1 > start1)
2107 *--buf0=*--buf1;
2108
2109 while (buf0 > to->buf)
2110 *--buf0=0;
2111
2112 return error;
2113 }
2114
decimal_intg(const decimal_t * from)2115 int decimal_intg(const decimal_t *from)
2116 {
2117 int res;
2118 remove_leading_zeroes(from, &res);
2119 return res;
2120 }
2121
decimal_add(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2122 int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2123 {
2124 if (likely(from1->sign == from2->sign))
2125 return do_add(from1, from2, to);
2126 return do_sub(from1, from2, to);
2127 }
2128
decimal_sub(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2129 int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2130 {
2131 if (likely(from1->sign == from2->sign))
2132 return do_sub(from1, from2, to);
2133 return do_add(from1, from2, to);
2134 }
2135
decimal_cmp(const decimal_t * from1,const decimal_t * from2)2136 int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
2137 {
2138 if (likely(from1->sign == from2->sign))
2139 return do_sub(from1, from2, 0);
2140 return from1->sign > from2->sign ? -1 : 1;
2141 }
2142
decimal_is_zero(const decimal_t * from)2143 int decimal_is_zero(const decimal_t *from)
2144 {
2145 dec1 *buf1=from->buf,
2146 *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2147 while (buf1 < end)
2148 if (*buf1++)
2149 return 0;
2150 return 1;
2151 }
2152
2153 /*
2154 multiply two decimals
2155
2156 SYNOPSIS
2157 decimal_mul()
2158 from1, from2 - factors
2159 to - product
2160
2161 RETURN VALUE
2162 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
2163
2164 NOTES
2165 in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
2166 and 63-digit number will take only 7 dec1 words (basically a 7-digit
2167 "base 999999999" number). Thus there's no need in fast multiplication
2168 algorithms, 7-digit numbers can be multiplied with a naive O(n*n)
2169 method.
2170
2171 XXX if this library is to be used with huge numbers of thousands of
2172 digits, fast multiplication must be implemented.
2173 */
decimal_mul(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2174 int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2175 {
2176 int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
2177 frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
2178 intg0=ROUND_UP(from1->intg+from2->intg),
2179 frac0=frac1+frac2, error, iii, jjj, d_to_move;
2180 dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
2181 *start2, *stop2, *stop1, *start0, carry;
2182
2183 sanity(to);
2184
2185 iii= intg0; /* save 'ideal' values */
2186 jjj= frac0;
2187 FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error); /* bound size */
2188 to->sign= from1->sign != from2->sign;
2189 to->frac= from1->frac + from2->frac; /* store size in digits */
2190 set_if_smaller(to->frac, NOT_FIXED_DEC);
2191 to->intg=intg0*DIG_PER_DEC1;
2192
2193 if (unlikely(error))
2194 {
2195 set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
2196 set_if_smaller(to->intg, intg0*DIG_PER_DEC1);
2197 if (unlikely(iii > intg0)) /* bounded integer-part */
2198 {
2199 iii-=intg0;
2200 jjj= iii >> 1;
2201 intg1-= jjj;
2202 intg2-=iii-jjj;
2203 frac1=frac2=0; /* frac0 is already 0 here */
2204 }
2205 else /* bounded fract part */
2206 {
2207 jjj-=frac0;
2208 iii=jjj >> 1;
2209 if (frac1 <= frac2)
2210 {
2211 frac1-= iii;
2212 frac2-=jjj-iii;
2213 }
2214 else
2215 {
2216 frac2-= iii;
2217 frac1-=jjj-iii;
2218 }
2219 }
2220 }
2221 start0=to->buf+intg0+frac0-1;
2222 start2=buf2+frac2-1;
2223 stop1=buf1-intg1;
2224 stop2=buf2-intg2;
2225
2226 memset(to->buf, 0, (intg0+frac0)*sizeof(dec1));
2227
2228 for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
2229 {
2230 carry=0;
2231 for (buf0=start0, buf2=start2; buf2 >= stop2; buf2--, buf0--)
2232 {
2233 dec1 hi, lo;
2234 dec2 p= ((dec2)*buf1) * ((dec2)*buf2);
2235 hi=(dec1)(p/DIG_BASE);
2236 lo=(dec1)(p-((dec2)hi)*DIG_BASE);
2237 ADD2(*buf0, *buf0, lo, carry);
2238 carry+=hi;
2239 }
2240 if (carry)
2241 {
2242 if (buf0 < to->buf)
2243 return E_DEC_OVERFLOW;
2244 ADD2(*buf0, *buf0, 0, carry);
2245 }
2246 for (buf0--; carry; buf0--)
2247 {
2248 if (buf0 < to->buf)
2249 return E_DEC_OVERFLOW;
2250 ADD(*buf0, *buf0, 0, carry);
2251 }
2252 }
2253
2254 /* Now we have to check for -0.000 case */
2255 if (to->sign)
2256 {
2257 dec1 *buf= to->buf;
2258 dec1 *end= to->buf + intg0 + frac0;
2259 DBUG_ASSERT(buf != end);
2260 for (;;)
2261 {
2262 if (*buf)
2263 break;
2264 if (++buf == end)
2265 {
2266 /* We got decimal zero */
2267 decimal_make_zero(to);
2268 break;
2269 }
2270 }
2271 }
2272 buf1= to->buf;
2273 d_to_move= intg0 + ROUND_UP(to->frac);
2274 while (!*buf1 && (to->intg > DIG_PER_DEC1))
2275 {
2276 buf1++;
2277 to->intg-= DIG_PER_DEC1;
2278 d_to_move--;
2279 }
2280 if (to->buf < buf1)
2281 {
2282 dec1 *cur_d= to->buf;
2283 for (; d_to_move--; cur_d++, buf1++)
2284 *cur_d= *buf1;
2285 }
2286 return error;
2287 }
2288
2289 /*
2290 naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2291 it's ok for short numbers
2292 also we're using alloca() to allocate a temporary buffer
2293
2294 XXX if this library is to be used with huge numbers of thousands of
2295 digits, fast division must be implemented and alloca should be
2296 changed to malloc (or at least fallback to malloc if alloca() fails)
2297 but then, decimal_mul() should be rewritten too :(
2298 */
do_div_mod(const decimal_t * from1,const decimal_t * from2,decimal_t * to,decimal_t * mod,int scale_incr)2299 static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2300 decimal_t *to, decimal_t *mod, int scale_incr)
2301 {
2302 int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2303 frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2304 UNINIT_VAR(error), i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2305 dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2306 *start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
2307 dec2 norm_factor, x, guess, y;
2308
2309 if (mod)
2310 to=mod;
2311
2312 sanity(to);
2313
2314 /* removing all the leading zeroes */
2315 i= ((prec2 - 1) % DIG_PER_DEC1) + 1;
2316 while (prec2 > 0 && *buf2 == 0)
2317 {
2318 prec2-= i;
2319 i= DIG_PER_DEC1;
2320 buf2++;
2321 }
2322 if (prec2 <= 0) /* short-circuit everything: from2 == 0 */
2323 return E_DEC_DIV_ZERO;
2324 prec2-= count_leading_zeroes((prec2 - 1) % DIG_PER_DEC1, *buf2);
2325 DBUG_ASSERT(prec2 > 0);
2326
2327 i=((prec1-1) % DIG_PER_DEC1)+1;
2328 while (prec1 > 0 && *buf1 == 0)
2329 {
2330 prec1-=i;
2331 i=DIG_PER_DEC1;
2332 buf1++;
2333 }
2334 if (prec1 <= 0)
2335 { /* short-circuit everything: from1 == 0 */
2336 decimal_make_zero(to);
2337 return E_DEC_OK;
2338 }
2339 prec1-= count_leading_zeroes((prec1-1) % DIG_PER_DEC1, *buf1);
2340 DBUG_ASSERT(prec1 > 0);
2341
2342 /* let's fix scale_incr, taking into account frac1,frac2 increase */
2343 if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0)
2344 scale_incr=0;
2345
2346 dintg=(prec1-frac1)-(prec2-frac2)+(*buf1 >= *buf2);
2347 if (dintg < 0)
2348 {
2349 dintg/=DIG_PER_DEC1;
2350 intg0=0;
2351 }
2352 else
2353 intg0=ROUND_UP(dintg);
2354 if (mod)
2355 {
2356 /* we're calculating N1 % N2.
2357 The result will have
2358 frac=max(frac1, frac2), as for subtraction
2359 intg=intg2
2360 */
2361 to->sign=from1->sign;
2362 to->frac= MY_MAX(from1->frac, from2->frac);
2363 frac0=0;
2364 }
2365 else
2366 {
2367 /*
2368 we're calculating N1/N2. N1 is in the buf1, has prec1 digits
2369 N2 is in the buf2, has prec2 digits. Scales are frac1 and
2370 frac2 accordingly.
2371 Thus, the result will have
2372 frac = ROUND_UP(frac1+frac2+scale_incr)
2373 and
2374 intg = (prec1-frac1) - (prec2-frac2) + 1
2375 prec = intg+frac
2376 */
2377 frac0=ROUND_UP(frac1+frac2+scale_incr);
2378 FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2379 to->sign=from1->sign != from2->sign;
2380 to->intg=intg0*DIG_PER_DEC1;
2381 to->frac=frac0*DIG_PER_DEC1;
2382 }
2383 buf0=to->buf;
2384 stop0=buf0+intg0+frac0;
2385 if (likely(div_mod))
2386 while (dintg++ < 0 && buf0 < &to->buf[to->len])
2387 {
2388 *buf0++=0;
2389 }
2390
2391 len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1;
2392 set_if_bigger(len1, 3);
2393 if (!(tmp1=(dec1 *)my_alloca(len1*sizeof(dec1))))
2394 return E_DEC_OOM;
2395 memcpy(tmp1, buf1, i*sizeof(dec1));
2396 memset(tmp1+i, 0, (len1-i)*sizeof(dec1));
2397
2398 start1=tmp1;
2399 stop1=start1+len1;
2400 start2=buf2;
2401 stop2=buf2+ROUND_UP(prec2)-1;
2402
2403 /* removing end zeroes */
2404 while (*stop2 == 0 && stop2 >= start2)
2405 stop2--;
2406 len2= (int) (stop2++ - start2);
2407
2408 /*
2409 calculating norm2 (normalized *start2) - we need *start2 to be large
2410 (at least > DIG_BASE/2), but unlike Knuth's Alg. D we don't want to
2411 normalize input numbers (as we don't make a copy of the divisor).
2412 Thus we normalize first dec1 of buf2 only, and we'll normalize *start1
2413 on the fly for the purpose of guesstimation only.
2414 It's also faster, as we're saving on normalization of buf2
2415 */
2416 norm_factor=DIG_BASE/(*start2+1);
2417 norm2=(dec1)(norm_factor*start2[0]);
2418 if (likely(len2>0))
2419 norm2+=(dec1)(norm_factor*start2[1]/DIG_BASE);
2420
2421 if (*start1 < *start2)
2422 dcarry=*start1++;
2423 else
2424 dcarry=0;
2425
2426 /* main loop */
2427 for (; buf0 < stop0; buf0++)
2428 {
2429 /* short-circuit, if possible */
2430 if (unlikely(dcarry == 0 && *start1 < *start2))
2431 guess=0;
2432 else
2433 {
2434 /* D3: make a guess */
2435 x=start1[0]+((dec2)dcarry)*DIG_BASE;
2436 y=start1[1];
2437 guess=(norm_factor*x+norm_factor*y/DIG_BASE)/norm2;
2438 if (unlikely(guess >= DIG_BASE))
2439 guess=DIG_BASE-1;
2440 if (likely(len2>0))
2441 {
2442 /* hmm, this is a suspicious trick - I removed normalization here */
2443 if (start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y)
2444 guess--;
2445 if (unlikely(start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y))
2446 guess--;
2447 DBUG_ASSERT(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
2448 }
2449
2450 /* D4: multiply and subtract */
2451 buf2=stop2;
2452 buf1=start1+len2;
2453 DBUG_ASSERT(buf1 < stop1);
2454 for (carry=0; buf2 > start2; buf1--)
2455 {
2456 dec1 hi, lo;
2457 x=guess * (*--buf2);
2458 hi=(dec1)(x/DIG_BASE);
2459 lo=(dec1)(x-((dec2)hi)*DIG_BASE);
2460 SUB2(*buf1, *buf1, lo, carry);
2461 carry+=hi;
2462 }
2463 carry= dcarry < carry;
2464
2465 /* D5: check the remainder */
2466 if (unlikely(carry))
2467 {
2468 /* D6: correct the guess */
2469 guess--;
2470 buf2=stop2;
2471 buf1=start1+len2;
2472 for (carry=0; buf2 > start2; buf1--)
2473 {
2474 ADD(*buf1, *buf1, *--buf2, carry);
2475 }
2476 }
2477 }
2478 if (likely(div_mod))
2479 {
2480 DBUG_ASSERT(buf0 < to->buf + to->len);
2481 *buf0=(dec1)guess;
2482 }
2483 dcarry= *start1;
2484 start1++;
2485 }
2486 if (mod)
2487 {
2488 /*
2489 now the result is in tmp1, it has
2490 intg=prec1-frac1
2491 frac=max(frac1, frac2)=to->frac
2492 */
2493 if (dcarry)
2494 *--start1=dcarry;
2495 buf0=to->buf;
2496 intg0=(int) (ROUND_UP(prec1-frac1)-(start1-tmp1));
2497 frac0=ROUND_UP(to->frac);
2498 error=E_DEC_OK;
2499 if (unlikely(frac0==0 && intg0==0))
2500 {
2501 decimal_make_zero(to);
2502 goto done;
2503 }
2504 if (intg0<=0)
2505 {
2506 if (unlikely(-intg0 >= to->len))
2507 {
2508 decimal_make_zero(to);
2509 error=E_DEC_TRUNCATED;
2510 goto done;
2511 }
2512 stop1= start1 + frac0 + intg0;
2513 frac0+=intg0;
2514 to->intg=0;
2515 while (intg0++ < 0)
2516 *buf0++=0;
2517 }
2518 else
2519 {
2520 if (unlikely(intg0 > to->len))
2521 {
2522 frac0=0;
2523 intg0=to->len;
2524 error=E_DEC_OVERFLOW;
2525 goto done;
2526 }
2527 DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
2528 stop1=start1+frac0+intg0;
2529 to->intg= MY_MIN(intg0 * DIG_PER_DEC1, from2->intg);
2530 }
2531 if (unlikely(intg0+frac0 > to->len))
2532 {
2533 stop1-=frac0+intg0-to->len;
2534 frac0=to->len-intg0;
2535 to->frac=frac0*DIG_PER_DEC1;
2536 error=E_DEC_TRUNCATED;
2537 }
2538 DBUG_ASSERT(buf0 + (stop1 - start1) <= to->buf + to->len);
2539 while (start1 < stop1)
2540 *buf0++=*start1++;
2541 }
2542 done:
2543 my_afree(tmp1);
2544 tmp1= remove_leading_zeroes(to, &to->intg);
2545 if(to->buf != tmp1)
2546 memmove(to->buf, tmp1,
2547 (ROUND_UP(to->intg) + ROUND_UP(to->frac)) * sizeof(dec1));
2548 return error;
2549 }
2550
2551 /*
2552 division of two decimals
2553
2554 SYNOPSIS
2555 decimal_div()
2556 from1 - dividend
2557 from2 - divisor
2558 to - quotient
2559
2560 RETURN VALUE
2561 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2562
2563 NOTES
2564 see do_div_mod()
2565 */
2566
2567 int
decimal_div(const decimal_t * from1,const decimal_t * from2,decimal_t * to,int scale_incr)2568 decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to,
2569 int scale_incr)
2570 {
2571 return do_div_mod(from1, from2, to, 0, scale_incr);
2572 }
2573
2574 /*
2575 modulus
2576
2577 SYNOPSIS
2578 decimal_mod()
2579 from1 - dividend
2580 from2 - divisor
2581 to - modulus
2582
2583 RETURN VALUE
2584 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2585
2586 NOTES
2587 see do_div_mod()
2588
2589 DESCRIPTION
2590 the modulus R in R = M mod N
2591
2592 is defined as
2593
2594 0 <= |R| < |M|
2595 sign R == sign M
2596 R = M - k*N, where k is integer
2597
2598 thus, there's no requirement for M or N to be integers
2599 */
2600
decimal_mod(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2601 int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2602 {
2603 return do_div_mod(from1, from2, 0, to, 0);
2604 }
2605
2606 #ifdef MAIN
2607 /*
2608 The main() program has been converted into a unit test.
2609 */
2610 #endif
2611