1 /* Copyright (c) 2004, 2021, Oracle and/or its affiliates.
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 #define sanity(d) assert((d)->len >0)
152
153 #define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error) \
154 do \
155 { \
156 if (unlikely(intg1+frac1 > (len))) \
157 { \
158 if (unlikely(intg1 > (len))) \
159 { \
160 intg1=(len); \
161 frac1=0; \
162 error=E_DEC_OVERFLOW; \
163 } \
164 else \
165 { \
166 frac1=(len)-intg1; \
167 error=E_DEC_TRUNCATED; \
168 } \
169 } \
170 else \
171 error=E_DEC_OK; \
172 } while(0)
173
174 #define ADD(to, from1, from2, carry) /* assume carry <= 1 */ \
175 do \
176 { \
177 dec1 a=(from1)+(from2)+(carry); \
178 assert((carry) <= 1); \
179 if (((carry)= a >= DIG_BASE)) /* no division here! */ \
180 a-=DIG_BASE; \
181 (to)=a; \
182 } while(0)
183
184 #define ADD2(to, from1, from2, carry) \
185 do \
186 { \
187 dec2 a=((dec2)(from1))+(from2)+(carry); \
188 if (((carry)= a >= DIG_BASE)) \
189 a-=DIG_BASE; \
190 if (unlikely(a >= DIG_BASE)) \
191 { \
192 a-=DIG_BASE; \
193 carry++; \
194 } \
195 (to)=(dec1) a; \
196 } while(0)
197
198 #define SUB(to, from1, from2, carry) /* to=from1-from2 */ \
199 do \
200 { \
201 dec1 a=(from1)-(from2)-(carry); \
202 if (((carry)= a < 0)) \
203 a+=DIG_BASE; \
204 (to)=a; \
205 } while(0)
206
207 #define SUB2(to, from1, from2, carry) /* to=from1-from2 */ \
208 do \
209 { \
210 dec1 a=(from1)-(from2)-(carry); \
211 if (((carry)= a < 0)) \
212 a+=DIG_BASE; \
213 if (unlikely(a < 0)) \
214 { \
215 a+=DIG_BASE; \
216 carry++; \
217 } \
218 (to)=a; \
219 } while(0)
220
221
222 /*
223 This is a direct loop unrolling of code that used to look like this:
224 for (; *buf_beg < powers10[i--]; start++) ;
225
226 @param i start index
227 @param val value to compare against list of powers of 10
228
229 @retval Number of leading zeroes that can be removed from fraction.
230
231 @note Why unroll? To get rid of lots of compiler warnings [-Warray-bounds]
232 Nice bonus: unrolled code is significantly faster.
233 */
count_leading_zeroes(int i,dec1 val)234 static inline int count_leading_zeroes(int i, dec1 val)
235 {
236 int ret= 0;
237 switch (i)
238 {
239 /* @note Intentional fallthrough in all case labels */
240 case 9: if (val >= 1000000000) break; ++ret; // Fall through.
241 case 8: if (val >= 100000000) break; ++ret; // Fall through.
242 case 7: if (val >= 10000000) break; ++ret; // Fall through.
243 case 6: if (val >= 1000000) break; ++ret; // Fall through.
244 case 5: if (val >= 100000) break; ++ret; // Fall through.
245 case 4: if (val >= 10000) break; ++ret; // Fall through.
246 case 3: if (val >= 1000) break; ++ret; // Fall through.
247 case 2: if (val >= 100) break; ++ret; // Fall through.
248 case 1: if (val >= 10) break; ++ret; // Fall through.
249 case 0: if (val >= 1) break; ++ret; // Fall through.
250 default: { assert(FALSE); }
251 }
252 return ret;
253 }
254
255 /*
256 This is a direct loop unrolling of code that used to look like this:
257 for (; *buf_end % powers10[i++] == 0; stop--) ;
258
259 @param i start index
260 @param val value to compare against list of powers of 10
261
262 @retval Number of trailing zeroes that can be removed from fraction.
263
264 @note Why unroll? To get rid of lots of compiler warnings [-Warray-bounds]
265 Nice bonus: unrolled code is significantly faster.
266 */
count_trailing_zeroes(int i,dec1 val)267 static inline int count_trailing_zeroes(int i, dec1 val)
268 {
269 int ret= 0;
270 switch(i)
271 {
272 /* @note Intentional fallthrough in all case labels */
273 case 0: if ((val % 1) != 0) break; ++ret; // Fall through.
274 case 1: if ((val % 10) != 0) break; ++ret; // Fall through.
275 case 2: if ((val % 100) != 0) break; ++ret; // Fall through.
276 case 3: if ((val % 1000) != 0) break; ++ret; // Fall through.
277 case 4: if ((val % 10000) != 0) break; ++ret; // Fall through.
278 case 5: if ((val % 100000) != 0) break; ++ret; // Fall through.
279 case 6: if ((val % 1000000) != 0) break; ++ret; // Fall through.
280 case 7: if ((val % 10000000) != 0) break; ++ret; // Fall through.
281 case 8: if ((val % 100000000) != 0) break; ++ret; // Fall through.
282 case 9: if ((val % 1000000000) != 0) break; ++ret; // Fall through.
283 default: { assert(FALSE); }
284 }
285 return ret;
286 }
287
288
289 /*
290 Get maximum value for given precision and scale
291
292 SYNOPSIS
293 max_decimal()
294 precision/scale - see decimal_bin_size() below
295 to - decimal where where the result will be stored
296 to->buf and to->len must be set.
297 */
298
max_decimal(int precision,int frac,decimal_t * to)299 void max_decimal(int precision, int frac, decimal_t *to)
300 {
301 int intpart;
302 dec1 *buf= to->buf;
303 assert(precision && precision >= frac);
304
305 to->sign= 0;
306 if ((intpart= to->intg= (precision - frac)))
307 {
308 int firstdigits= intpart % DIG_PER_DEC1;
309 if (firstdigits)
310 *buf++= powers10[firstdigits] - 1; /* get 9 99 999 ... */
311 for(intpart/= DIG_PER_DEC1; intpart; intpart--)
312 *buf++= DIG_MAX;
313 }
314
315 if ((to->frac= frac))
316 {
317 int lastdigits= frac % DIG_PER_DEC1;
318 for(frac/= DIG_PER_DEC1; frac; frac--)
319 *buf++= DIG_MAX;
320 if (lastdigits)
321 *buf= frac_max[lastdigits - 1];
322 }
323 }
324
325
remove_leading_zeroes(const decimal_t * from,int * intg_result)326 static dec1 *remove_leading_zeroes(const decimal_t *from, int *intg_result)
327 {
328 int intg= from->intg, i;
329 dec1 *buf0= from->buf;
330 i= ((intg - 1) % DIG_PER_DEC1) + 1;
331 while (intg > 0 && *buf0 == 0)
332 {
333 intg-= i;
334 i= DIG_PER_DEC1;
335 buf0++;
336 }
337 if (intg > 0)
338 {
339 intg-= count_leading_zeroes((intg - 1) % DIG_PER_DEC1, *buf0);
340 assert(intg > 0);
341 }
342 else
343 intg=0;
344 *intg_result= intg;
345 return buf0;
346 }
347
348
349 /*
350 Count actual length of fraction part (without ending zeroes)
351
352 SYNOPSIS
353 decimal_actual_fraction()
354 from number for processing
355 */
356
decimal_actual_fraction(decimal_t * from)357 int decimal_actual_fraction(decimal_t *from)
358 {
359 int frac= from->frac, i;
360 dec1 *buf0= from->buf + ROUND_UP(from->intg) + ROUND_UP(frac) - 1;
361
362 if (frac == 0)
363 return 0;
364
365 i= ((frac - 1) % DIG_PER_DEC1 + 1);
366 while (frac > 0 && *buf0 == 0)
367 {
368 frac-= i;
369 i= DIG_PER_DEC1;
370 buf0--;
371 }
372 if (frac > 0)
373 {
374 frac-=
375 count_trailing_zeroes(DIG_PER_DEC1 - ((frac - 1) % DIG_PER_DEC1), *buf0);
376 }
377 return frac;
378 }
379
380
381 /*
382 Convert decimal to its printable string representation
383
384 SYNOPSIS
385 decimal2string()
386 from - value to convert
387 to - points to buffer where string representation
388 should be stored
389 *to_len - in: size of to buffer (incl. terminating '\0')
390 out: length of the actually written string (excl. '\0')
391 fixed_precision - 0 if representation can be variable length and
392 fixed_decimals will not be checked in this case.
393 Put number as with fixed point position with this
394 number of digits (sign counted and decimal point is
395 counted)
396 fixed_decimals - number digits after point.
397 filler - character to fill gaps in case of fixed_precision > 0
398
399 RETURN VALUE
400 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
401 */
402
decimal2string(const decimal_t * from,char * to,int * to_len,int fixed_precision,int fixed_decimals,char filler)403 int decimal2string(const decimal_t *from, char *to, int *to_len,
404 int fixed_precision, int fixed_decimals,
405 char filler)
406 {
407 /* {intg_len, frac_len} output widths; {intg, frac} places in input */
408 int len, intg, frac= from->frac, i, intg_len, frac_len, fill;
409 /* number digits before decimal point */
410 int fixed_intg= (fixed_precision ?
411 (fixed_precision - fixed_decimals) : 0);
412 int error=E_DEC_OK;
413 char *s=to;
414 dec1 *buf, *buf0=from->buf, tmp;
415
416 assert(*to_len >= 2+from->sign);
417
418 /* removing leading zeroes */
419 buf0= remove_leading_zeroes(from, &intg);
420 if (unlikely(intg+frac==0))
421 {
422 intg=1;
423 tmp=0;
424 buf0=&tmp;
425 }
426
427 if (!(intg_len= fixed_precision ? fixed_intg : intg))
428 intg_len= 1;
429 frac_len= fixed_precision ? fixed_decimals : frac;
430 len= from->sign + intg_len + MY_TEST(frac) + frac_len;
431 if (fixed_precision)
432 {
433 if (frac > fixed_decimals)
434 {
435 error= E_DEC_TRUNCATED;
436 frac= fixed_decimals;
437 }
438 if (intg > fixed_intg)
439 {
440 error= E_DEC_OVERFLOW;
441 intg= fixed_intg;
442 }
443 }
444 else if (unlikely(len > --*to_len)) /* reserve one byte for \0 */
445 {
446 int j= len - *to_len; /* excess printable chars */
447 error= (frac && j <= frac + 1) ? E_DEC_TRUNCATED : E_DEC_OVERFLOW;
448
449 /*
450 If we need to cut more places than frac is wide, we'll end up
451 dropping the decimal point as well. Account for this.
452 */
453 if (frac && j >= frac + 1)
454 j--;
455
456 if (j > frac)
457 {
458 intg_len= intg-= j-frac;
459 frac= 0;
460 }
461 else
462 frac-=j;
463 frac_len= frac;
464 len= from->sign + intg_len + MY_TEST(frac) + frac_len;
465 }
466 *to_len= len;
467 s[len]= 0;
468
469 if (from->sign)
470 *s++='-';
471
472 if (frac)
473 {
474 char *s1= s + intg_len;
475 fill= frac_len - frac;
476 buf=buf0+ROUND_UP(intg);
477 *s1++='.';
478 for (; frac>0; frac-=DIG_PER_DEC1)
479 {
480 dec1 x=*buf++;
481 for (i= MY_MIN(frac, DIG_PER_DEC1); i; i--)
482 {
483 dec1 y=x/DIG_MASK;
484 *s1++='0'+(uchar)y;
485 x-=y*DIG_MASK;
486 x*=10;
487 }
488 }
489 for(; fill > 0; fill--)
490 *s1++=filler;
491 }
492
493 fill= intg_len - intg;
494 if (intg == 0)
495 fill--; /* symbol 0 before digital point */
496 for(; fill > 0; fill--)
497 *s++=filler;
498 if (intg)
499 {
500 s+=intg;
501 for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
502 {
503 dec1 x=*--buf;
504 for (i= MY_MIN(intg, DIG_PER_DEC1); i; i--)
505 {
506 dec1 y=x/10;
507 *--s='0'+(uchar)(x-y*10);
508 x=y;
509 }
510 }
511 }
512 else
513 *s= '0';
514
515 return error;
516 }
517
518
519 /*
520 Return bounds of decimal digits in the number
521
522 SYNOPSIS
523 digits_bounds()
524 from - decimal number for processing
525 start_result - index (from 0 ) of first decimal digits will
526 be written by this address
527 end_result - index of position just after last decimal digit
528 be written by this address
529 */
530
digits_bounds(decimal_t * from,int * start_result,int * end_result)531 static void digits_bounds(decimal_t *from, int *start_result, int *end_result)
532 {
533 int start, stop, i;
534 dec1 *buf_beg= from->buf;
535 dec1 *end= from->buf + ROUND_UP(from->intg) + ROUND_UP(from->frac);
536 dec1 *buf_end= end - 1;
537
538 /* find non-zero digit from number begining */
539 while (buf_beg < end && *buf_beg == 0)
540 buf_beg++;
541
542 if (buf_beg >= end)
543 {
544 /* it is zero */
545 *start_result= *end_result= 0;
546 return;
547 }
548
549 /* find non-zero decimal digit from number begining */
550 if (buf_beg == from->buf && from->intg)
551 {
552 start= DIG_PER_DEC1 - (i= ((from->intg-1) % DIG_PER_DEC1 + 1));
553 i--;
554 }
555 else
556 {
557 i= DIG_PER_DEC1 - 1;
558 start= (int) ((buf_beg - from->buf) * DIG_PER_DEC1);
559 }
560 if (buf_beg < end)
561 start+= count_leading_zeroes(i, *buf_beg);
562
563 *start_result= start; /* index of first decimal digit (from 0) */
564
565 /* find non-zero digit at the end */
566 while (buf_end > buf_beg && *buf_end == 0)
567 buf_end--;
568 /* find non-zero decimal digit from the end */
569 if (buf_end == end - 1 && from->frac)
570 {
571 stop= (int) (((buf_end - from->buf) * DIG_PER_DEC1 +
572 (i= ((from->frac - 1) % DIG_PER_DEC1 + 1))));
573 i= DIG_PER_DEC1 - i + 1;
574 }
575 else
576 {
577 stop= (int) ((buf_end - from->buf + 1) * DIG_PER_DEC1);
578 i= 1;
579 }
580 stop-= count_trailing_zeroes(i, *buf_end);
581 *end_result= stop; /* index of position after last decimal digit (from 0) */
582 }
583
584
585 /*
586 Left shift for alignment of data in buffer
587
588 SYNOPSIS
589 do_mini_left_shift()
590 dec pointer to decimal number which have to be shifted
591 shift number of decimal digits on which it should be shifted
592 beg/end bounds of decimal digits (see digits_bounds())
593
594 NOTE
595 Result fitting in the buffer should be garanted.
596 'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
597 */
598
do_mini_left_shift(decimal_t * dec,int shift,int beg,int last)599 void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
600 {
601 dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
602 dec1 *end= dec->buf + ROUND_UP(last) - 1;
603 int c_shift= DIG_PER_DEC1 - shift;
604 assert(from >= dec->buf);
605 assert(end < dec->buf + dec->len);
606 if (beg % DIG_PER_DEC1 < shift)
607 *(from - 1)= (*from) / powers10[c_shift];
608 for(; from < end; from++)
609 *from= ((*from % powers10[c_shift]) * powers10[shift] +
610 (*(from + 1)) / powers10[c_shift]);
611 *from= (*from % powers10[c_shift]) * powers10[shift];
612 }
613
614
615 /*
616 Right shift for alignment of data in buffer
617
618 SYNOPSIS
619 do_mini_left_shift()
620 dec pointer to decimal number which have to be shifted
621 shift number of decimal digits on which it should be shifted
622 beg/end bounds of decimal digits (see digits_bounds())
623
624 NOTE
625 Result fitting in the buffer should be garanted.
626 'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
627 */
628
do_mini_right_shift(decimal_t * dec,int shift,int beg,int last)629 void do_mini_right_shift(decimal_t *dec, int shift, int beg, int last)
630 {
631 dec1 *from= dec->buf + ROUND_UP(last) - 1;
632 dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1;
633 int c_shift= DIG_PER_DEC1 - shift;
634 assert(from < dec->buf + dec->len);
635 assert(end >= dec->buf);
636 if (DIG_PER_DEC1 - ((last - 1) % DIG_PER_DEC1 + 1) < shift)
637 *(from + 1)= (*from % powers10[shift]) * powers10[c_shift];
638 for(; from > end; from--)
639 *from= (*from / powers10[shift] +
640 (*(from - 1) % powers10[shift]) * powers10[c_shift]);
641 *from= *from / powers10[shift];
642 }
643
644
645 /*
646 Shift of decimal digits in given number (with rounding if it need)
647
648 SYNOPSIS
649 decimal_shift()
650 dec number to be shifted
651 shift number of decimal positions
652 shift > 0 means shift to left shift
653 shift < 0 meand right shift
654 NOTE
655 In fact it is multipling on 10^shift.
656 RETURN
657 E_DEC_OK OK
658 E_DEC_OVERFLOW operation lead to overflow, number is untoched
659 E_DEC_TRUNCATED number was rounded to fit into buffer
660 */
661
decimal_shift(decimal_t * dec,int shift)662 int decimal_shift(decimal_t *dec, int shift)
663 {
664 /* index of first non zero digit (all indexes from 0) */
665 int beg;
666 /* index of position after last decimal digit */
667 int end;
668 /* index of digit position just after point */
669 int point= ROUND_UP(dec->intg) * DIG_PER_DEC1;
670 /* new point position */
671 int new_point= point + shift;
672 /* number of digits in result */
673 int digits_int, digits_frac;
674 /* length of result and new fraction in big digits*/
675 int new_len, new_frac_len;
676 /* return code */
677 int err= E_DEC_OK;
678 int new_front;
679
680 if (shift == 0)
681 return E_DEC_OK;
682
683 digits_bounds(dec, &beg, &end);
684
685 if (beg == end)
686 {
687 decimal_make_zero(dec);
688 return E_DEC_OK;
689 }
690
691 digits_int= new_point - beg;
692 set_if_bigger(digits_int, 0);
693 digits_frac= end - new_point;
694 set_if_bigger(digits_frac, 0);
695
696 if ((new_len= ROUND_UP(digits_int) + (new_frac_len= ROUND_UP(digits_frac))) >
697 dec->len)
698 {
699 int lack= new_len - dec->len;
700 int diff;
701
702 if (new_frac_len < lack)
703 return E_DEC_OVERFLOW; /* lack more then we have in fraction */
704
705 /* cat off fraction part to allow new number to fit in our buffer */
706 err= E_DEC_TRUNCATED;
707 new_frac_len-= lack;
708 diff= digits_frac - (new_frac_len * DIG_PER_DEC1);
709 /* Make rounding method as parameter? */
710 decimal_round(dec, dec, end - point - diff, HALF_UP);
711 end-= diff;
712 digits_frac= new_frac_len * DIG_PER_DEC1;
713
714 if (end <= beg)
715 {
716 /*
717 we lost all digits (they will be shifted out of buffer), so we can
718 just return 0
719 */
720 decimal_make_zero(dec);
721 return E_DEC_TRUNCATED;
722 }
723 }
724
725 if (shift % DIG_PER_DEC1)
726 {
727 int l_mini_shift, r_mini_shift, mini_shift;
728 int do_left;
729 /*
730 Calculate left/right shift to align decimal digits inside our bug
731 digits correctly
732 */
733 if (shift > 0)
734 {
735 l_mini_shift= shift % DIG_PER_DEC1;
736 r_mini_shift= DIG_PER_DEC1 - l_mini_shift;
737 /*
738 It is left shift so prefer left shift, but if we have not place from
739 left, we have to have it from right, because we checked length of
740 result
741 */
742 do_left= l_mini_shift <= beg;
743 assert(do_left || (dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
744 }
745 else
746 {
747 r_mini_shift= (-shift) % DIG_PER_DEC1;
748 l_mini_shift= DIG_PER_DEC1 - r_mini_shift;
749 /* see comment above */
750 do_left= !((dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
751 assert(!do_left || l_mini_shift <= beg);
752 }
753 if (do_left)
754 {
755 do_mini_left_shift(dec, l_mini_shift, beg, end);
756 mini_shift= -l_mini_shift;
757 }
758 else
759 {
760 do_mini_right_shift(dec, r_mini_shift, beg, end);
761 mini_shift= r_mini_shift;
762 }
763 new_point+= mini_shift;
764 /*
765 If number is shifted and correctly aligned in buffer we can
766 finish
767 */
768 if (!(shift+= mini_shift) && (new_point - digits_int) < DIG_PER_DEC1)
769 {
770 dec->intg= digits_int;
771 dec->frac= digits_frac;
772 return err; /* already shifted as it should be */
773 }
774 beg+= mini_shift;
775 end+= mini_shift;
776 }
777
778 /* if new 'decimal front' is in first digit, we do not need move digits */
779 if ((new_front= (new_point - digits_int)) >= DIG_PER_DEC1 ||
780 new_front < 0)
781 {
782 /* need to move digits */
783 int d_shift;
784 dec1 *to, *barier;
785 if (new_front > 0)
786 {
787 /* move left */
788 d_shift= new_front / DIG_PER_DEC1;
789 to= dec->buf + (ROUND_UP(beg + 1) - 1 - d_shift);
790 barier= dec->buf + (ROUND_UP(end) - 1 - d_shift);
791 assert(to >= dec->buf);
792 assert(barier + d_shift < dec->buf + dec->len);
793 for(; to <= barier; to++)
794 *to= *(to + d_shift);
795 for(barier+= d_shift; to <= barier; to++)
796 *to= 0;
797 d_shift= -d_shift;
798 }
799 else
800 {
801 /* move right */
802 d_shift= (1 - new_front) / DIG_PER_DEC1;
803 to= dec->buf + ROUND_UP(end) - 1 + d_shift;
804 barier= dec->buf + ROUND_UP(beg + 1) - 1 + d_shift;
805 assert(to < dec->buf + dec->len);
806 assert(barier - d_shift >= dec->buf);
807 for(; to >= barier; to--)
808 *to= *(to - d_shift);
809 for(barier-= d_shift; to >= barier; to--)
810 *to= 0;
811 }
812 d_shift*= DIG_PER_DEC1;
813 beg+= d_shift;
814 end+= d_shift;
815 new_point+= d_shift;
816 }
817
818 /*
819 If there are gaps then fill ren with 0.
820
821 Only one of following 'for' loops will work becouse beg <= end
822 */
823 beg= ROUND_UP(beg + 1) - 1;
824 end= ROUND_UP(end) - 1;
825 assert(new_point >= 0);
826
827 /* We don't want negative new_point below */
828 if (new_point != 0)
829 new_point= ROUND_UP(new_point) - 1;
830
831 if (new_point > end)
832 {
833 do
834 {
835 dec->buf[new_point]=0;
836 } while (--new_point > end);
837 }
838 else
839 {
840 for (; new_point < beg; new_point++)
841 dec->buf[new_point]= 0;
842 }
843 dec->intg= digits_int;
844 dec->frac= digits_frac;
845 return err;
846 }
847
848
849 /*
850 Convert string to decimal
851
852 SYNOPSIS
853 internal_str2decl()
854 from - value to convert. Doesn't have to be \0 terminated!
855 to - decimal where where the result will be stored
856 to->buf and to->len must be set.
857 end - Pointer to pointer to end of string. Will on return be
858 set to the char after the last used character
859 fixed - use to->intg, to->frac as limits for input number
860
861 NOTE
862 to->intg and to->frac can be modified even when fixed=1
863 (but only decreased, in this case)
864
865 RETURN VALUE
866 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_BAD_NUM/E_DEC_OOM
867 In case of E_DEC_FATAL_ERROR *to is set to decimal zero
868 (to make error handling easier)
869 */
870
871 int
internal_str2dec(const char * from,decimal_t * to,char ** end,my_bool fixed)872 internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed)
873 {
874 const char *s= from, *s1, *endp, *end_of_string= *end;
875 int i, intg, frac, error, intg1, frac1;
876 dec1 x,*buf;
877 sanity(to);
878
879 error= E_DEC_BAD_NUM; /* In case of bad number */
880 while (s < end_of_string && my_isspace(&my_charset_latin1, *s))
881 s++;
882 if (s == end_of_string)
883 goto fatal_error;
884
885 if ((to->sign= (*s == '-')))
886 s++;
887 else if (*s == '+')
888 s++;
889
890 s1=s;
891 while (s < end_of_string && my_isdigit(&my_charset_latin1, *s))
892 s++;
893 intg= (int) (s-s1);
894 if (s < end_of_string && *s=='.')
895 {
896 endp= s+1;
897 while (endp < end_of_string && my_isdigit(&my_charset_latin1, *endp))
898 endp++;
899 frac= (int) (endp - s - 1);
900 }
901 else
902 {
903 frac= 0;
904 endp= s;
905 }
906
907 *end= (char*) endp;
908
909 if (frac+intg == 0)
910 goto fatal_error;
911
912 error= 0;
913 if (fixed)
914 {
915 if (frac > to->frac)
916 {
917 error=E_DEC_TRUNCATED;
918 frac=to->frac;
919 }
920 if (intg > to->intg)
921 {
922 error=E_DEC_OVERFLOW;
923 intg=to->intg;
924 }
925 intg1=ROUND_UP(intg);
926 frac1=ROUND_UP(frac);
927 if (intg1+frac1 > to->len)
928 {
929 error= E_DEC_OOM;
930 goto fatal_error;
931 }
932 }
933 else
934 {
935 intg1=ROUND_UP(intg);
936 frac1=ROUND_UP(frac);
937 FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
938 if (unlikely(error))
939 {
940 frac=frac1*DIG_PER_DEC1;
941 if (error == E_DEC_OVERFLOW)
942 intg=intg1*DIG_PER_DEC1;
943 }
944 }
945 /* Error is guranteed to be set here */
946 to->intg=intg;
947 to->frac=frac;
948
949 buf=to->buf+intg1;
950 s1=s;
951
952 for (x=0, i=0; intg; intg--)
953 {
954 x+= (*--s - '0')*powers10[i];
955
956 if (unlikely(++i == DIG_PER_DEC1))
957 {
958 *--buf=x;
959 x=0;
960 i=0;
961 }
962 }
963 if (i)
964 *--buf=x;
965
966 buf=to->buf+intg1;
967 for (x=0, i=0; frac; frac--)
968 {
969 x= (*++s1 - '0') + x*10;
970
971 if (unlikely(++i == DIG_PER_DEC1))
972 {
973 *buf++=x;
974 x=0;
975 i=0;
976 }
977 }
978 if (i)
979 *buf=x*powers10[DIG_PER_DEC1-i];
980
981 /* Handle exponent */
982 if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
983 {
984 int str_error;
985 longlong exponent= my_strtoll10(endp+1, (char**) &end_of_string,
986 &str_error);
987
988 if (end_of_string != endp +1) /* If at least one digit */
989 {
990 *end= (char*) end_of_string;
991 if (str_error > 0)
992 {
993 error= E_DEC_BAD_NUM;
994 goto fatal_error;
995 }
996 if (exponent > INT_MAX/2 || (str_error == 0 && exponent < 0))
997 {
998 error= E_DEC_OVERFLOW;
999 goto fatal_error;
1000 }
1001 if (exponent < INT_MIN/2 && error != E_DEC_OVERFLOW)
1002 {
1003 error= E_DEC_TRUNCATED;
1004 goto fatal_error;
1005 }
1006 if (error != E_DEC_OVERFLOW)
1007 error= decimal_shift(to, (int) exponent);
1008 }
1009 }
1010 /* Avoid returning negative zero, cfr. decimal_cmp() */
1011 if (to->sign && decimal_is_zero(to))
1012 to->sign= FALSE;
1013 return error;
1014
1015 fatal_error:
1016 decimal_make_zero(to);
1017 return error;
1018 }
1019
1020
1021 /*
1022 Convert decimal to double
1023
1024 SYNOPSIS
1025 decimal2double()
1026 from - value to convert
1027 to - result will be stored there
1028
1029 RETURN VALUE
1030 E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1031 */
1032
decimal2double(const decimal_t * from,double * to)1033 int decimal2double(const decimal_t *from, double *to)
1034 {
1035 char strbuf[FLOATING_POINT_BUFFER], *end;
1036 int len= sizeof(strbuf);
1037 int rc, error;
1038
1039 rc = decimal2string(from, strbuf, &len, 0, 0, 0);
1040 end= strbuf + len;
1041
1042 DBUG_PRINT("info", ("interm.: %s", strbuf));
1043
1044 *to= my_strtod(strbuf, &end, &error);
1045
1046 DBUG_PRINT("info", ("result: %f", *to));
1047
1048 return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
1049 }
1050
1051 /*
1052 Convert double to decimal
1053
1054 SYNOPSIS
1055 double2decimal()
1056 from - value to convert
1057 to - result will be stored there
1058
1059 RETURN VALUE
1060 E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1061 */
1062
double2decimal(double from,decimal_t * to)1063 int double2decimal(double from, decimal_t *to)
1064 {
1065 char buff[FLOATING_POINT_BUFFER], *end;
1066 int res;
1067 DBUG_ENTER("double2decimal");
1068 end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, (int)sizeof(buff) - 1, buff, NULL);
1069 res= string2decimal(buff, to, &end);
1070 DBUG_PRINT("exit", ("res: %d", res));
1071 DBUG_RETURN(res);
1072 }
1073
1074
ull2dec(ulonglong from,decimal_t * to)1075 static int ull2dec(ulonglong from, decimal_t *to)
1076 {
1077 int intg1;
1078 int error= E_DEC_OK;
1079 ulonglong x= from;
1080 dec1 *buf;
1081
1082 sanity(to);
1083
1084 if (from == 0)
1085 intg1= 1;
1086 else
1087 {
1088 /* Count the number of decimal_digit_t's we need. */
1089 for (intg1= 0; from != 0; intg1++, from/= DIG_BASE)
1090 ;
1091 }
1092 if (unlikely(intg1 > to->len))
1093 {
1094 intg1= to->len;
1095 error= E_DEC_OVERFLOW;
1096 }
1097 to->frac= 0;
1098 to->intg= intg1 * DIG_PER_DEC1;
1099
1100 for (buf= to->buf + intg1; intg1; intg1--)
1101 {
1102 ulonglong y= x / DIG_BASE;
1103 *--buf=(dec1)(x - y * DIG_BASE);
1104 x= y;
1105 }
1106 return error;
1107 }
1108
ulonglong2decimal(ulonglong from,decimal_t * to)1109 int ulonglong2decimal(ulonglong from, decimal_t *to)
1110 {
1111 to->sign=0;
1112 return ull2dec(from, to);
1113 }
1114
longlong2decimal(longlong from,decimal_t * to)1115 int longlong2decimal(longlong from, decimal_t *to)
1116 {
1117 if ((to->sign= from < 0))
1118 return ull2dec(-from, to);
1119 return ull2dec(from, to);
1120 }
1121
decimal2ulonglong(decimal_t * from,ulonglong * to)1122 int decimal2ulonglong(decimal_t *from, ulonglong *to)
1123 {
1124 dec1 *buf=from->buf;
1125 ulonglong x=0;
1126 int intg, frac;
1127
1128 if (from->sign)
1129 {
1130 *to=0ULL;
1131 return E_DEC_OVERFLOW;
1132 }
1133
1134 for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1135 {
1136 ulonglong y=x;
1137 x=x*DIG_BASE + *buf++;
1138 if (unlikely(y > ((ulonglong) ULLONG_MAX/DIG_BASE) || x < y))
1139 {
1140 *to=ULLONG_MAX;
1141 return E_DEC_OVERFLOW;
1142 }
1143 }
1144 *to=x;
1145 for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1146 if (*buf++)
1147 return E_DEC_TRUNCATED;
1148 return E_DEC_OK;
1149 }
1150
decimal2longlong(decimal_t * from,longlong * to)1151 int decimal2longlong(decimal_t *from, longlong *to)
1152 {
1153 dec1 *buf=from->buf;
1154 longlong x=0;
1155 int intg, frac;
1156
1157 for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1158 {
1159 longlong y=x;
1160 /*
1161 Attention: trick!
1162 we're calculating -|from| instead of |from| here
1163 because |LLONG_MIN| > LLONG_MAX
1164 so we can convert -9223372036854775808 correctly
1165 */
1166 x=x*DIG_BASE - *buf++;
1167 if (unlikely(y < (LLONG_MIN/DIG_BASE) || x > y))
1168 {
1169 /*
1170 the decimal is bigger than any possible integer
1171 return border integer depending on the sign
1172 */
1173 *to= from->sign ? LLONG_MIN : LLONG_MAX;
1174 return E_DEC_OVERFLOW;
1175 }
1176 }
1177 /* boundary case: 9223372036854775808 */
1178 if (unlikely(from->sign==0 && x == LLONG_MIN))
1179 {
1180 *to= LLONG_MAX;
1181 return E_DEC_OVERFLOW;
1182 }
1183
1184 *to=from->sign ? x : -x;
1185 for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1186 if (*buf++)
1187 return E_DEC_TRUNCATED;
1188 return E_DEC_OK;
1189 }
1190
1191
1192 #define LLDIV_MIN -1000000000000000000LL
1193 #define LLDIV_MAX 1000000000000000000LL
1194
1195 /**
1196 Convert decimal value to lldiv_t value.
1197 @param from The decimal value to convert from.
1198 @param OUT to The lldiv_t variable to convert to.
1199 @return 0 on success, error code on error.
1200 */
decimal2lldiv_t(const decimal_t * from,lldiv_t * to)1201 int decimal2lldiv_t(const decimal_t *from, lldiv_t *to)
1202 {
1203 int int_part= ROUND_UP(from->intg);
1204 int frac_part= ROUND_UP(from->frac);
1205 if (int_part > 2)
1206 {
1207 to->rem= 0;
1208 to->quot= from->sign ? LLDIV_MIN : LLDIV_MAX;
1209 return E_DEC_OVERFLOW;
1210 }
1211 if (int_part == 2)
1212 to->quot= ((longlong) from->buf[0]) * DIG_BASE + from->buf[1];
1213 else if (int_part == 1)
1214 to->quot= from->buf[0];
1215 else
1216 to->quot= 0;
1217 to->rem= frac_part ? from->buf[int_part] : 0;
1218 if (from->sign)
1219 {
1220 to->quot= -to->quot;
1221 to->rem= -to->rem;
1222 }
1223 return 0;
1224 }
1225
1226
1227 /**
1228 Convert double value to lldiv_t valie.
1229 @param from The double value to convert from.
1230 @param OUT to The lldit_t variable to convert to.
1231 @return 0 on success, error code on error.
1232
1233 Integer part goes into lld.quot.
1234 Fractional part multiplied to 1000000000 (10^9) goes to lld.rem.
1235 Typically used in datetime calculations to split seconds
1236 and nanoseconds.
1237 */
double2lldiv_t(double nr,lldiv_t * lld)1238 int double2lldiv_t(double nr, lldiv_t *lld)
1239 {
1240 if (nr > LLDIV_MAX)
1241 {
1242 lld->quot= LLDIV_MAX;
1243 lld->rem= 0;
1244 return E_DEC_OVERFLOW;
1245 }
1246 else if (nr < LLDIV_MIN)
1247 {
1248 lld->quot= LLDIV_MIN;
1249 lld->rem= 0;
1250 return E_DEC_OVERFLOW;
1251 }
1252 /* Truncate fractional part toward zero and store into "quot" */
1253 lld->quot= (longlong) (nr > 0 ? floor(nr) : ceil(nr));
1254 /* Multiply reminder to 10^9 and store into "rem" */
1255 lld->rem= (longlong) rint((nr - (double) lld->quot) * 1000000000);
1256 /*
1257 Sometimes the expression "(double) 0.999999999xxx * (double) 10e9"
1258 gives 1,000,000,000 instead of 999,999,999 due to lack of double precision.
1259 The callers do not expect lld->rem to be greater than 999,999,999.
1260 Let's catch this corner case and put the "nanounit" (e.g. nanosecond)
1261 value in ldd->rem back into the valid range.
1262 */
1263 if (lld->rem > 999999999LL)
1264 lld->rem= 999999999LL;
1265 else if (lld->rem < -999999999LL)
1266 lld->rem= -999999999LL;
1267 return E_DEC_OK;
1268 }
1269
1270
1271
1272 /*
1273 Convert decimal to its binary fixed-length representation
1274 two representations of the same length can be compared with memcmp
1275 with the correct -1/0/+1 result
1276
1277 SYNOPSIS
1278 decimal2bin()
1279 from - value to convert
1280 to - points to buffer where string representation should be stored
1281 precision/scale - see decimal_bin_size() below
1282
1283 NOTE
1284 the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1285
1286 RETURN VALUE
1287 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1288
1289 DESCRIPTION
1290 for storage decimal numbers are converted to the "binary" format.
1291
1292 This format has the following properties:
1293 1. length of the binary representation depends on the {precision, scale}
1294 as provided by the caller and NOT on the intg/frac of the decimal to
1295 convert.
1296 2. binary representations of the same {precision, scale} can be compared
1297 with memcmp - with the same result as decimal_cmp() of the original
1298 decimals (not taking into account possible precision loss during
1299 conversion).
1300
1301 This binary format is as follows:
1302 1. First the number is converted to have a requested precision and scale.
1303 2. Every full DIG_PER_DEC1 digits of intg part are stored in 4 bytes
1304 as is
1305 3. The first intg % DIG_PER_DEC1 digits are stored in the reduced
1306 number of bytes (enough bytes to store this number of digits -
1307 see dig2bytes)
1308 4. same for frac - full decimal_digit_t's are stored as is,
1309 the last frac % DIG_PER_DEC1 digits - in the reduced number of bytes.
1310 5. If the number is negative - every byte is inversed.
1311 5. The very first bit of the resulting byte array is inverted (because
1312 memcmp compares unsigned bytes, see property 2 above)
1313
1314 Example:
1315
1316 1234567890.1234
1317
1318 internally is represented as 3 decimal_digit_t's
1319
1320 1 234567890 123400000
1321
1322 (assuming we want a binary representation with precision=14, scale=4)
1323 in hex it's
1324
1325 00-00-00-01 0D-FB-38-D2 07-5A-EF-40
1326
1327 now, middle decimal_digit_t is full - it stores 9 decimal digits. It goes
1328 into binary representation as is:
1329
1330
1331 ........... 0D-FB-38-D2 ............
1332
1333 First decimal_digit_t has only one decimal digit. We can store one digit in
1334 one byte, no need to waste four:
1335
1336 01 0D-FB-38-D2 ............
1337
1338 now, last digit. It's 123400000. We can store 1234 in two bytes:
1339
1340 01 0D-FB-38-D2 04-D2
1341
1342 So, we've packed 12 bytes number in 7 bytes.
1343 And now we invert the highest bit to get the final result:
1344
1345 81 0D FB 38 D2 04 D2
1346
1347 And for -1234567890.1234 it would be
1348
1349 7E F2 04 C7 2D FB 2D
1350 */
decimal2bin(decimal_t * from,uchar * to,int precision,int frac)1351 int decimal2bin(decimal_t *from, uchar *to, int precision, int frac)
1352 {
1353 dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1354 int error=E_DEC_OK, intg=precision-frac,
1355 isize1, intg1, intg1x, from_intg,
1356 intg0=intg/DIG_PER_DEC1,
1357 frac0=frac/DIG_PER_DEC1,
1358 intg0x=intg-intg0*DIG_PER_DEC1,
1359 frac0x=frac-frac0*DIG_PER_DEC1,
1360 frac1=from->frac/DIG_PER_DEC1,
1361 frac1x=from->frac-frac1*DIG_PER_DEC1,
1362 isize0=intg0*sizeof(dec1)+dig2bytes[intg0x],
1363 fsize0=frac0*sizeof(dec1)+dig2bytes[frac0x],
1364 fsize1=frac1*sizeof(dec1)+dig2bytes[frac1x];
1365 const int orig_isize0= isize0;
1366 const int orig_fsize0= fsize0;
1367 uchar *orig_to= to;
1368
1369 buf1= remove_leading_zeroes(from, &from_intg);
1370
1371 if (unlikely(from_intg+fsize1==0))
1372 {
1373 mask=0; /* just in case */
1374 intg=1;
1375 buf1=&mask;
1376 }
1377
1378 intg1=from_intg/DIG_PER_DEC1;
1379 intg1x=from_intg-intg1*DIG_PER_DEC1;
1380 isize1=intg1*sizeof(dec1)+dig2bytes[intg1x];
1381
1382 if (intg < from_intg)
1383 {
1384 buf1+=intg1-intg0+(intg1x>0)-(intg0x>0);
1385 intg1=intg0; intg1x=intg0x;
1386 error=E_DEC_OVERFLOW;
1387 }
1388 else if (isize0 > isize1)
1389 {
1390 while (isize0-- > isize1)
1391 *to++= (char)mask;
1392 }
1393 if (fsize0 < fsize1)
1394 {
1395 frac1=frac0; frac1x=frac0x;
1396 error=E_DEC_TRUNCATED;
1397 }
1398 else if (fsize0 > fsize1 && frac1x)
1399 {
1400 if (frac0 == frac1)
1401 {
1402 frac1x=frac0x;
1403 fsize0= fsize1;
1404 }
1405 else
1406 {
1407 frac1++;
1408 frac1x=0;
1409 }
1410 }
1411
1412 /* intg1x part */
1413 if (intg1x)
1414 {
1415 int i=dig2bytes[intg1x];
1416 dec1 x=(*buf1++ % powers10[intg1x]) ^ mask;
1417 switch (i)
1418 {
1419 case 1: mi_int1store(to, x); break;
1420 case 2: mi_int2store(to, x); break;
1421 case 3: mi_int3store(to, x); break;
1422 case 4: mi_int4store(to, x); break;
1423 default: assert(0);
1424 }
1425 to+=i;
1426 }
1427
1428 /* intg1+frac1 part */
1429 for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=sizeof(dec1))
1430 {
1431 dec1 x=*buf1++ ^ mask;
1432 assert(sizeof(dec1) == 4);
1433 mi_int4store(to, x);
1434 }
1435
1436 /* frac1x part */
1437 if (frac1x)
1438 {
1439 dec1 x;
1440 int i=dig2bytes[frac1x],
1441 lim=(frac1 < frac0 ? DIG_PER_DEC1 : frac0x);
1442 while (frac1x < lim && dig2bytes[frac1x] == i)
1443 frac1x++;
1444 x=(*buf1 / powers10[DIG_PER_DEC1 - frac1x]) ^ mask;
1445 switch (i)
1446 {
1447 case 1: mi_int1store(to, x); break;
1448 case 2: mi_int2store(to, x); break;
1449 case 3: mi_int3store(to, x); break;
1450 case 4: mi_int4store(to, x); break;
1451 default: assert(0);
1452 }
1453 to+=i;
1454 }
1455 if (fsize0 > fsize1)
1456 {
1457 uchar *to_end= orig_to + orig_fsize0 + orig_isize0;
1458
1459 while (fsize0-- > fsize1 && to < to_end)
1460 *to++= (uchar)mask;
1461 }
1462 orig_to[0]^= 0x80;
1463
1464 /* Check that we have written the whole decimal and nothing more */
1465 assert(to == orig_to + orig_fsize0 + orig_isize0);
1466 return error;
1467 }
1468
1469 /*
1470 Restores decimal from its binary fixed-length representation
1471
1472 SYNOPSIS
1473 bin2decimal()
1474 from - value to convert
1475 to - result
1476 precision/scale - see decimal_bin_size() below
1477
1478 NOTE
1479 see decimal2bin()
1480 the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1481
1482 RETURN VALUE
1483 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1484 */
1485
bin2decimal(const uchar * from,decimal_t * to,int precision,int scale)1486 int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale)
1487 {
1488 int error=E_DEC_OK, intg=precision-scale,
1489 intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1490 intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
1491 intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
1492 dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
1493 const uchar *stop;
1494 uchar *d_copy;
1495 int bin_size= decimal_bin_size(precision, scale);
1496
1497 sanity(to);
1498 d_copy= (uchar*) my_alloca(bin_size);
1499 memcpy(d_copy, from, bin_size);
1500 d_copy[0]^= 0x80;
1501 from= d_copy;
1502
1503 FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
1504 if (unlikely(error))
1505 {
1506 if (intg1 < intg0+(intg0x>0))
1507 {
1508 from+=dig2bytes[intg0x]+sizeof(dec1)*(intg0-intg1);
1509 frac0=frac0x=intg0x=0;
1510 intg0=intg1;
1511 }
1512 else
1513 {
1514 frac0x=0;
1515 frac0=frac1;
1516 }
1517 }
1518
1519 to->sign=(mask != 0);
1520 to->intg=intg0*DIG_PER_DEC1+intg0x;
1521 to->frac=frac0*DIG_PER_DEC1+frac0x;
1522
1523 if (intg0x)
1524 {
1525 int i=dig2bytes[intg0x];
1526 dec1 x= 0;
1527 switch (i)
1528 {
1529 case 1: x=mi_sint1korr(from); break;
1530 case 2: x=mi_sint2korr(from); break;
1531 case 3: x=mi_sint3korr(from); break;
1532 case 4: x=mi_sint4korr(from); break;
1533 default: assert(0);
1534 }
1535 from+=i;
1536 *buf=x ^ mask;
1537 if (((ulonglong)*buf) >= (ulonglong) powers10[intg0x+1])
1538 goto err;
1539 if (buf > to->buf || *buf != 0)
1540 buf++;
1541 else
1542 to->intg-=intg0x;
1543 }
1544 for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1545 {
1546 assert(sizeof(dec1) == 4);
1547 *buf=mi_sint4korr(from) ^ mask;
1548 if (((uint32)*buf) > DIG_MAX)
1549 goto err;
1550 if (buf > to->buf || *buf != 0)
1551 buf++;
1552 else
1553 to->intg-=DIG_PER_DEC1;
1554 }
1555 assert(to->intg >=0);
1556 for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1557 {
1558 assert(sizeof(dec1) == 4);
1559 *buf=mi_sint4korr(from) ^ mask;
1560 if (((uint32)*buf) > DIG_MAX)
1561 goto err;
1562 buf++;
1563 }
1564 if (frac0x)
1565 {
1566 int i=dig2bytes[frac0x];
1567 dec1 x= 0;
1568 switch (i)
1569 {
1570 case 1: x=mi_sint1korr(from); break;
1571 case 2: x=mi_sint2korr(from); break;
1572 case 3: x=mi_sint3korr(from); break;
1573 case 4: x=mi_sint4korr(from); break;
1574 default: assert(0);
1575 }
1576 *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
1577 if (((uint32)*buf) > DIG_MAX)
1578 goto err;
1579 buf++;
1580 }
1581
1582 /*
1583 No digits? We have read the number zero, of unspecified precision.
1584 Make it a proper zero, with non-zero precision.
1585 */
1586 if (to->intg == 0 && to->frac == 0)
1587 decimal_make_zero(to);
1588 return error;
1589
1590 err:
1591 decimal_make_zero(to);
1592 return(E_DEC_BAD_NUM);
1593 }
1594
1595 /*
1596 Returns the size of array to hold a decimal with given precision and scale
1597
1598 RETURN VALUE
1599 size in dec1
1600 (multiply by sizeof(dec1) to get the size if bytes)
1601 */
1602
decimal_size(int precision,int scale)1603 int decimal_size(int precision, int scale)
1604 {
1605 assert(scale >= 0 && precision > 0 && scale <= precision);
1606 return ROUND_UP(precision-scale)+ROUND_UP(scale);
1607 }
1608
1609 /*
1610 Returns the size of array to hold a binary representation of a decimal
1611
1612 RETURN VALUE
1613 size in bytes
1614 */
1615
decimal_bin_size(int precision,int scale)1616 int decimal_bin_size(int precision, int scale)
1617 {
1618 int intg=precision-scale,
1619 intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1620 intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1;
1621
1622 assert(scale >= 0 && precision > 0 && scale <= precision);
1623 assert(intg0x >= 0);
1624 assert(intg0x <= DIG_PER_DEC1);
1625 assert(frac0x >= 0);
1626 assert(frac0x <= DIG_PER_DEC1);
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), round_digit= 0,
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: 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 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 assert(p0 - buf0 <= len);
1696 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 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 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 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: 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 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
2141 // Reject negative zero, cfr. internal_str2dec()
2142 assert(!(decimal_is_zero(from1) && from1->sign));
2143 assert(!(decimal_is_zero(from2) && from2->sign));
2144
2145 return from1->sign > from2->sign ? -1 : 1;
2146 }
2147
decimal_is_zero(const decimal_t * from)2148 int decimal_is_zero(const decimal_t *from)
2149 {
2150 dec1 *buf1=from->buf,
2151 *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2152 while (buf1 < end)
2153 if (*buf1++)
2154 return 0;
2155 return 1;
2156 }
2157
2158 /*
2159 multiply two decimals
2160
2161 SYNOPSIS
2162 decimal_mul()
2163 from1, from2 - factors
2164 to - product
2165
2166 RETURN VALUE
2167 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
2168
2169 NOTES
2170 in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
2171 and 63-digit number will take only 7 dec1 words (basically a 7-digit
2172 "base 999999999" number). Thus there's no need in fast multiplication
2173 algorithms, 7-digit numbers can be multiplied with a naive O(n*n)
2174 method.
2175
2176 XXX if this library is to be used with huge numbers of thousands of
2177 digits, fast multiplication must be implemented.
2178 */
decimal_mul(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2179 int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2180 {
2181 int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
2182 frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
2183 intg0=ROUND_UP(from1->intg+from2->intg),
2184 frac0=frac1+frac2, error, iii, jjj, d_to_move;
2185 dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
2186 *start2, *stop2, *stop1, *start0, carry;
2187
2188 sanity(to);
2189
2190 iii= intg0; /* save 'ideal' values */
2191 jjj= frac0;
2192 FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error); /* bound size */
2193 to->sign= from1->sign != from2->sign;
2194 to->frac= from1->frac + from2->frac; /* store size in digits */
2195 set_if_smaller(to->frac, NOT_FIXED_DEC);
2196 to->intg=intg0*DIG_PER_DEC1;
2197
2198 if (unlikely(error))
2199 {
2200 set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
2201 set_if_smaller(to->intg, intg0*DIG_PER_DEC1);
2202 if (unlikely(iii > intg0)) /* bounded integer-part */
2203 {
2204 iii-=intg0;
2205 jjj= iii >> 1;
2206 intg1-= jjj;
2207 intg2-=iii-jjj;
2208 frac1=frac2=0; /* frac0 is already 0 here */
2209 }
2210 else /* bounded fract part */
2211 {
2212 jjj-=frac0;
2213 iii=jjj >> 1;
2214 if (frac1 <= frac2)
2215 {
2216 frac1-= iii;
2217 frac2-=jjj-iii;
2218 }
2219 else
2220 {
2221 frac2-= iii;
2222 frac1-=jjj-iii;
2223 }
2224 }
2225 }
2226 start0=to->buf+intg0+frac0-1;
2227 start2=buf2+frac2-1;
2228 stop1=buf1-intg1;
2229 stop2=buf2-intg2;
2230
2231 memset(to->buf, 0, (intg0+frac0)*sizeof(dec1));
2232
2233 for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
2234 {
2235 carry=0;
2236 for (buf0=start0, buf2=start2; buf2 >= stop2; buf2--, buf0--)
2237 {
2238 dec1 hi, lo;
2239 dec2 p= ((dec2)*buf1) * ((dec2)*buf2);
2240 hi=(dec1)(p/DIG_BASE);
2241 lo=(dec1)(p-((dec2)hi)*DIG_BASE);
2242 ADD2(*buf0, *buf0, lo, carry);
2243 carry+=hi;
2244 }
2245 if (carry)
2246 {
2247 if (buf0 < to->buf)
2248 return E_DEC_OVERFLOW;
2249 ADD2(*buf0, *buf0, 0, carry);
2250 }
2251 for (buf0--; carry; buf0--)
2252 {
2253 if (buf0 < to->buf)
2254 return E_DEC_OVERFLOW;
2255 ADD(*buf0, *buf0, 0, carry);
2256 }
2257 }
2258
2259 /* Now we have to check for -0.000 case */
2260 if (to->sign)
2261 {
2262 dec1 *buf= to->buf;
2263 dec1 *end= to->buf + intg0 + frac0;
2264 assert(buf != end);
2265 for (;;)
2266 {
2267 if (*buf)
2268 break;
2269 if (++buf == end)
2270 {
2271 /* We got decimal zero */
2272 decimal_make_zero(to);
2273 break;
2274 }
2275 }
2276 }
2277 buf1= to->buf;
2278 d_to_move= intg0 + ROUND_UP(to->frac);
2279 while (!*buf1 && (to->intg > DIG_PER_DEC1))
2280 {
2281 buf1++;
2282 to->intg-= DIG_PER_DEC1;
2283 d_to_move--;
2284 }
2285 if (to->buf < buf1)
2286 {
2287 dec1 *cur_d= to->buf;
2288 for (; d_to_move--; cur_d++, buf1++)
2289 *cur_d= *buf1;
2290 }
2291 return error;
2292 }
2293
2294 /*
2295 naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2296 it's ok for short numbers
2297 also we're using alloca() to allocate a temporary buffer
2298
2299 XXX if this library is to be used with huge numbers of thousands of
2300 digits, fast division must be implemented and alloca should be
2301 changed to malloc (or at least fallback to malloc if alloca() fails)
2302 but then, decimal_mul() should be rewritten too :(
2303 */
do_div_mod(const decimal_t * from1,const decimal_t * from2,decimal_t * to,decimal_t * mod,int scale_incr)2304 static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2305 decimal_t *to, decimal_t *mod, int scale_incr)
2306 {
2307
2308 /*
2309 frac* - number of digits in fractional part of the number
2310 prec* - precision of the number
2311 intg* - number of digits in the integer part
2312 buf* - buffer having the actual number
2313 All variables ending with 0 - like frac0, intg0 etc are
2314 for the final result. Similarly frac1, intg1 etc are for
2315 the first number and frac2, intg2 etc are for the second number
2316 */
2317 int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2318 frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2319 error= 0, i, intg0, frac0, len1, len2,
2320 dintg, /* Holds the estimate of number of integer digits in final result */
2321 div_mod=(!mod) /*true if this is division */;
2322 dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *start1, *stop1,
2323 *start2, *stop2, *stop0 ,norm2, carry, dcarry, *tmp1;
2324 dec2 norm_factor, x, guess, y;
2325
2326 if (mod)
2327 to=mod;
2328
2329 sanity(to);
2330
2331 /*
2332 removing all the leading zeroes in the second number. Leading zeroes are
2333 added later to the result.
2334 */
2335 i= ((prec2 - 1) % DIG_PER_DEC1) + 1;
2336 while (prec2 > 0 && *buf2 == 0)
2337 {
2338 prec2-= i;
2339 i= DIG_PER_DEC1;
2340 buf2++;
2341 }
2342 if (prec2 <= 0) /* short-circuit everything: from2 == 0 */
2343 return E_DEC_DIV_ZERO;
2344
2345 /*
2346 Remove the remanining zeroes . For ex: for 0.000000000001
2347 the above while loop removes 9 zeroes and the result will have 0.0001
2348 these remaining zeroes are removed here
2349 */
2350 prec2-= count_leading_zeroes((prec2 - 1) % DIG_PER_DEC1, *buf2);
2351 assert(prec2 > 0);
2352
2353 /*
2354 Do the same for the first number. Remove the leading zeroes.
2355 Check if the number is actually 0. Then remove the remaining zeroes.
2356 */
2357
2358 i=((prec1-1) % DIG_PER_DEC1)+1;
2359 while (prec1 > 0 && *buf1 == 0)
2360 {
2361 prec1-=i;
2362 i=DIG_PER_DEC1;
2363 buf1++;
2364 }
2365 if (prec1 <= 0)
2366 { /* short-circuit everything: from1 == 0 */
2367 decimal_make_zero(to);
2368 return E_DEC_OK;
2369 }
2370 prec1-= count_leading_zeroes((prec1-1) % DIG_PER_DEC1, *buf1);
2371 assert(prec1 > 0);
2372
2373 /* let's fix scale_incr, taking into account frac1,frac2 increase */
2374 if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0)
2375 scale_incr=0;
2376
2377 /* Calculate the integer digits in final result */
2378 dintg=(prec1-frac1)-(prec2-frac2)+(*buf1 >= *buf2);
2379 if (dintg < 0)
2380 {
2381 dintg/=DIG_PER_DEC1;
2382 intg0=0;
2383 }
2384 else
2385 intg0=ROUND_UP(dintg);
2386 if (mod)
2387 {
2388 /* we're calculating N1 % N2.
2389 The result will have
2390 frac=max(frac1, frac2), as for subtraction
2391 intg=intg2
2392 */
2393 to->sign=from1->sign;
2394 to->frac= MY_MAX(from1->frac, from2->frac);
2395 frac0=0;
2396 }
2397 else
2398 {
2399 /*
2400 we're calculating N1/N2. N1 is in the buf1, has prec1 digits
2401 N2 is in the buf2, has prec2 digits. Scales are frac1 and
2402 frac2 accordingly.
2403 Thus, the result will have
2404 frac = ROUND_UP(frac1+frac2+scale_incr)
2405 and
2406 intg = (prec1-frac1) - (prec2-frac2) + 1
2407 prec = intg+frac
2408 */
2409 frac0=ROUND_UP(frac1+frac2+scale_incr);
2410 FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2411 to->sign=from1->sign != from2->sign;
2412 to->intg=intg0*DIG_PER_DEC1;
2413 to->frac=frac0*DIG_PER_DEC1;
2414 }
2415 buf0=to->buf;
2416 stop0=buf0+intg0+frac0;
2417 if (likely(div_mod))
2418 while (dintg++ < 0 && buf0 < &to->buf[to->len])
2419 {
2420 *buf0++=0;
2421 }
2422
2423 len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1;
2424 set_if_bigger(len1, 3);
2425 if (!(tmp1=(dec1 *)my_alloca(len1*sizeof(dec1))))
2426 return E_DEC_OOM;
2427 memcpy(tmp1, buf1, i*sizeof(dec1));
2428 memset(tmp1+i, 0, (len1-i)*sizeof(dec1));
2429
2430 start1=tmp1;
2431 stop1=start1+len1;
2432 start2=buf2;
2433 stop2=buf2+ROUND_UP(prec2)-1;
2434
2435 /* removing end zeroes */
2436 while (*stop2 == 0 && stop2 >= start2)
2437 stop2--;
2438 len2= (int) (stop2++ - start2);
2439
2440 /*
2441 calculating norm2 (normalized *start2) - we need *start2 to be large
2442 (at least > DIG_BASE/2), but unlike Knuth's Alg. D we don't want to
2443 normalize input numbers (as we don't make a copy of the divisor).
2444 Thus we normalize first dec1 of buf2 only, and we'll normalize *start1
2445 on the fly for the purpose of guesstimation only.
2446 It's also faster, as we're saving on normalization of buf2
2447 */
2448 norm_factor=DIG_BASE/(*start2+1);
2449 norm2=(dec1)(norm_factor*start2[0]);
2450 if (likely(len2>0))
2451 norm2+=(dec1)(norm_factor*start2[1]/DIG_BASE);
2452
2453 if (*start1 < *start2)
2454 dcarry=*start1++;
2455 else
2456 dcarry=0;
2457
2458 /* main loop */
2459 for (; buf0 < stop0; buf0++)
2460 {
2461 /* short-circuit, if possible */
2462 if (unlikely(dcarry == 0 && *start1 < *start2))
2463 guess=0;
2464 else
2465 {
2466 /* D3: make a guess */
2467 x=start1[0]+((dec2)dcarry)*DIG_BASE;
2468 y=start1[1];
2469 guess=(norm_factor*x+norm_factor*y/DIG_BASE)/norm2;
2470 if (unlikely(guess >= DIG_BASE))
2471 guess=DIG_BASE-1;
2472 if (likely(len2>0))
2473 {
2474 /* hmm, this is a suspicious trick - I removed normalization here */
2475 if (start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y)
2476 guess--;
2477 if (unlikely(start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y))
2478 guess--;
2479 assert(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
2480 }
2481
2482 /* D4: multiply and subtract */
2483 buf2=stop2;
2484 buf1=start1+len2;
2485 assert(buf1 < stop1);
2486 for (carry=0; buf2 > start2; buf1--)
2487 {
2488 dec1 hi, lo;
2489 x=guess * (*--buf2);
2490 hi=(dec1)(x/DIG_BASE);
2491 lo=(dec1)(x-((dec2)hi)*DIG_BASE);
2492 SUB2(*buf1, *buf1, lo, carry);
2493 carry+=hi;
2494 }
2495 carry= dcarry < carry;
2496
2497 /* D5: check the remainder */
2498 if (unlikely(carry))
2499 {
2500 /* D6: correct the guess */
2501 guess--;
2502 buf2=stop2;
2503 buf1=start1+len2;
2504 for (carry=0; buf2 > start2; buf1--)
2505 {
2506 ADD(*buf1, *buf1, *--buf2, carry);
2507 }
2508 }
2509 }
2510 if (likely(div_mod))
2511 {
2512 assert(buf0 < to->buf + to->len);
2513 *buf0=(dec1)guess;
2514 }
2515 dcarry= *start1;
2516 start1++;
2517 }
2518 if (mod)
2519 {
2520 /*
2521 now the result is in tmp1, it has
2522 intg=prec1-frac1 if there were no leading zeroes.
2523 If leading zeroes were present, they have been removed
2524 earlier. We need to now add them back to the result.
2525 frac=max(frac1, frac2)=to->frac
2526 */
2527 if (dcarry)
2528 *--start1=dcarry;
2529 buf0=to->buf;
2530 /* Calculate the final result's integer digits */
2531 dintg= (prec1 - frac1) - ((start1 - tmp1) * DIG_PER_DEC1);
2532 if (dintg < 0)
2533 {
2534 /* If leading zeroes in the fractional part were earlier stripped */
2535 intg0= dintg / DIG_PER_DEC1;
2536 }
2537 else
2538 intg0= ROUND_UP(dintg);
2539 frac0=ROUND_UP(to->frac);
2540 error=E_DEC_OK;
2541 if (unlikely(frac0==0 && intg0==0))
2542 {
2543 decimal_make_zero(to);
2544 goto done;
2545 }
2546 if (intg0<=0)
2547 {
2548 /* Add back the leading zeroes that were earlier stripped */
2549 if (unlikely(-intg0 >= to->len))
2550 {
2551 decimal_make_zero(to);
2552 error=E_DEC_TRUNCATED;
2553 goto done;
2554 }
2555 stop1= start1 + frac0 + intg0;
2556 frac0+=intg0;
2557 to->intg=0;
2558 while (intg0++ < 0)
2559 *buf0++=0;
2560 }
2561 else
2562 {
2563 if (unlikely(intg0 > to->len))
2564 {
2565 frac0=0;
2566 intg0=to->len;
2567 error=E_DEC_OVERFLOW;
2568 goto done;
2569 }
2570 assert(intg0 <= ROUND_UP(from2->intg));
2571 stop1=start1+frac0+intg0;
2572 to->intg= MY_MIN(intg0 * DIG_PER_DEC1, from2->intg);
2573 }
2574 if (unlikely(intg0+frac0 > to->len))
2575 {
2576 stop1-=frac0+intg0-to->len;
2577 frac0=to->len-intg0;
2578 to->frac=frac0*DIG_PER_DEC1;
2579 error=E_DEC_TRUNCATED;
2580 }
2581 assert(buf0 + (stop1 - start1) <= to->buf + to->len);
2582 while (start1 < stop1)
2583 *buf0++=*start1++;
2584 }
2585 done:
2586 tmp1= remove_leading_zeroes(to, &to->intg);
2587 if(to->buf != tmp1)
2588 memmove(to->buf, tmp1,
2589 (ROUND_UP(to->intg) + ROUND_UP(to->frac)) * sizeof(dec1));
2590 return error;
2591 }
2592
2593 /*
2594 division of two decimals
2595
2596 SYNOPSIS
2597 decimal_div()
2598 from1 - dividend
2599 from2 - divisor
2600 to - quotient
2601
2602 RETURN VALUE
2603 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2604
2605 NOTES
2606 see do_div_mod()
2607 */
2608
2609 int
decimal_div(const decimal_t * from1,const decimal_t * from2,decimal_t * to,int scale_incr)2610 decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to,
2611 int scale_incr)
2612 {
2613 return do_div_mod(from1, from2, to, 0, scale_incr);
2614 }
2615
2616 /*
2617 modulus
2618
2619 SYNOPSIS
2620 decimal_mod()
2621 from1 - dividend
2622 from2 - divisor
2623 to - modulus
2624
2625 RETURN VALUE
2626 E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2627
2628 NOTES
2629 see do_div_mod()
2630
2631 DESCRIPTION
2632 the modulus R in R = M mod N
2633
2634 is defined as
2635
2636 0 <= |R| < |M|
2637 sign R == sign M
2638 R = M - k*N, where k is integer
2639
2640 thus, there's no requirement for M or N to be integers
2641 */
2642
decimal_mod(const decimal_t * from1,const decimal_t * from2,decimal_t * to)2643 int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2644 {
2645 return do_div_mod(from1, from2, 0, to, 0);
2646 }
2647
2648 #ifdef MAIN
2649 /*
2650 The main() program has been converted into a unit test.
2651 */
2652 #endif
2653