~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
#line 18 "decimal.c"
17
18
/*
19
=======================================================================
20
  NOTE: this library implements SQL standard "exact numeric" type
21
  and is not at all generic, but rather intentinally crippled to
22
  follow the standard :)
23
=======================================================================
24
  Quoting the standard
25
  (SQL:2003, Part 2 Foundations, aka ISO/IEC 9075-2:2003)
26
27
4.4.2 Characteristics of numbers, page 27:
28
29
  An exact numeric type has a precision P and a scale S. P is a positive
30
  integer that determines the number of significant digits in a
31
  particular radix R, where R is either 2 or 10. S is a non-negative
32
  integer. Every value of an exact numeric type of scale S is of the
33
  form n*10^{-S}, where n is an integer such that ­-R^P <= n <= R^P.
34
35
  [...]
36
37
  If an assignment of some number would result in a loss of its most
38
  significant digit, an exception condition is raised. If least
39
  significant digits are lost, implementation-defined rounding or
40
  truncating occurs, with no exception condition being raised.
41
42
  [...]
43
44
  Whenever an exact or approximate numeric value is assigned to an exact
45
  numeric value site, an approximation of its value that preserves
46
  leading significant digits after rounding or truncating is represented
47
  in the declared type of the target. The value is converted to have the
48
  precision and scale of the target. The choice of whether to truncate
49
  or round is implementation-defined.
50
51
  [...]
52
53
  All numeric values between the smallest and the largest value,
54
  inclusive, in a given exact numeric type have an approximation
55
  obtained by rounding or truncation for that type; it is
56
  implementation-defined which other numeric values have such
57
  approximations.
58
59
5.3 <literal>, page 143
60
61
  <exact numeric literal> ::=
62
    <unsigned integer> [ <period> [ <unsigned integer> ] ]
63
  | <period> <unsigned integer>
64
65
6.1 <data type>, page 165:
66
67
  19) The <scale> of an <exact numeric type> shall not be greater than
68
      the <precision> of the <exact numeric type>.
69
70
  20) For the <exact numeric type>s DECIMAL and NUMERIC:
71
72
    a) The maximum value of <precision> is implementation-defined.
73
       <precision> shall not be greater than this value.
74
    b) The maximum value of <scale> is implementation-defined. <scale>
75
       shall not be greater than this maximum value.
76
77
  21) NUMERIC specifies the data type exact numeric, with the decimal
78
      precision and scale specified by the <precision> and <scale>.
79
80
  22) DECIMAL specifies the data type exact numeric, with the decimal
81
      scale specified by the <scale> and the implementation-defined
82
      decimal precision equal to or greater than the value of the
83
      specified <precision>.
84
85
6.26 <numeric value expression>, page 241:
86
87
  1) If the declared type of both operands of a dyadic arithmetic
88
     operator is exact numeric, then the declared type of the result is
89
     an implementation-defined exact numeric type, with precision and
90
     scale determined as follows:
91
92
   a) Let S1 and S2 be the scale of the first and second operands
93
      respectively.
94
   b) The precision of the result of addition and subtraction is
95
      implementation-defined, and the scale is the maximum of S1 and S2.
96
   c) The precision of the result of multiplication is
97
      implementation-defined, and the scale is S1 + S2.
98
   d) The precision and scale of the result of division are
99
      implementation-defined.
100
*/
101
102
#include <my_global.h>
103
#include <m_ctype.h>
104
#include <myisampack.h>
105
#include <my_sys.h> /* for my_alloca */
106
#include <m_string.h>
107
#include <decimal.h>
108
109
/*
110
  Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
111
  So one variable of type decimal_digit_t is limited:
112
113
      0 < decimal_digit <= DIG_MAX < DIG_BASE
114
115
  in the struct st_decimal_t:
116
117
    intg is the number of *decimal* digits (NOT number of decimal_digit_t's !)
118
         before the point
119
    frac - number of decimal digits after the point
120
    buf is an array of decimal_digit_t's
121
    len is the length of buf (length of allocated space) in decimal_digit_t's,
122
        not in bytes
123
*/
124
typedef decimal_digit_t dec1;
152 by Brian Aker
longlong replacement
125
typedef int64_t      dec2;
1 by brian
clean slate
126
127
#define DIG_PER_DEC1 9
128
#define DIG_MASK     100000000
129
#define DIG_BASE     1000000000
130
#define DIG_MAX      (DIG_BASE-1)
131
#define DIG_BASE2    ((dec2)DIG_BASE * (dec2)DIG_BASE)
132
#define ROUND_UP(X)  (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
133
static const dec1 powers10[DIG_PER_DEC1+1]={
134
  1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
135
static const int dig2bytes[DIG_PER_DEC1+1]={0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
136
static const dec1 frac_max[DIG_PER_DEC1-1]={
137
  900000000, 990000000, 999000000,
138
  999900000, 999990000, 999999000,
139
  999999900, 999999990 };
140
141
#ifdef HAVE_purify
142
#define sanity(d) DBUG_ASSERT((d)->len > 0)
143
#else
144
#define sanity(d) DBUG_ASSERT((d)->len >0 && ((d)->buf[0] | \
145
                              (d)->buf[(d)->len-1] | 1))
146
#endif
147
148
#define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error)                   \
149
        do                                                              \
150
        {                                                               \
151
          if (unlikely(intg1+frac1 > (len)))                            \
152
          {                                                             \
153
            if (unlikely(intg1 > (len)))                                \
154
            {                                                           \
155
              intg1=(len);                                              \
156
              frac1=0;                                                  \
157
              error=E_DEC_OVERFLOW;                                     \
158
            }                                                           \
159
            else                                                        \
160
            {                                                           \
161
              frac1=(len)-intg1;                                        \
162
              error=E_DEC_TRUNCATED;                                    \
163
            }                                                           \
164
          }                                                             \
165
          else                                                          \
166
            error=E_DEC_OK;                                             \
167
        } while(0)
168
169
#define ADD(to, from1, from2, carry)  /* assume carry <= 1 */           \
170
        do                                                              \
171
        {                                                               \
172
          dec1 a=(from1)+(from2)+(carry);                               \
173
          DBUG_ASSERT((carry) <= 1);                                    \
174
          if (((carry)= a >= DIG_BASE)) /* no division here! */         \
175
            a-=DIG_BASE;                                                \
176
          (to)=a;                                                       \
177
        } while(0)
178
179
#define ADD2(to, from1, from2, carry)                                   \
180
        do                                                              \
181
        {                                                               \
182
          dec2 a=((dec2)(from1))+(from2)+(carry);                       \
183
          if (((carry)= a >= DIG_BASE))                                 \
184
            a-=DIG_BASE;                                                \
185
          if (unlikely(a >= DIG_BASE))                                  \
186
          {                                                             \
187
            a-=DIG_BASE;                                                \
188
            carry++;                                                    \
189
          }                                                             \
190
          (to)=(dec1) a;                                                \
191
        } while(0)
192
193
#define SUB(to, from1, from2, carry) /* to=from1-from2 */               \
194
        do                                                              \
195
        {                                                               \
196
          dec1 a=(from1)-(from2)-(carry);                               \
197
          if (((carry)= a < 0))                                         \
198
            a+=DIG_BASE;                                                \
199
          (to)=a;                                                       \
200
        } while(0)
201
202
#define SUB2(to, from1, from2, carry) /* to=from1-from2 */              \
203
        do                                                              \
204
        {                                                               \
205
          dec1 a=(from1)-(from2)-(carry);                               \
206
          if (((carry)= a < 0))                                         \
207
            a+=DIG_BASE;                                                \
208
          if (unlikely(a < 0))                                          \
209
          {                                                             \
210
            a+=DIG_BASE;                                                \
211
            carry++;                                                    \
212
          }                                                             \
213
          (to)=a;                                                       \
214
        } while(0)
215
216
/*
217
  Get maximum value for given precision and scale
218
219
  SYNOPSIS
220
    max_decimal()
221
    precision/scale - see decimal_bin_size() below
222
    to              - decimal where where the result will be stored
223
                      to->buf and to->len must be set.
224
*/
225
226
void max_decimal(int precision, int frac, decimal_t *to)
227
{
228
  int intpart;
229
  dec1 *buf= to->buf;
230
  DBUG_ASSERT(precision && precision >= frac);
231
232
  to->sign= 0;
233
  if ((intpart= to->intg= (precision - frac)))
234
  {
235
    int firstdigits= intpart % DIG_PER_DEC1;
236
    if (firstdigits)
237
      *buf++= powers10[firstdigits] - 1; /* get 9 99 999 ... */
238
    for(intpart/= DIG_PER_DEC1; intpart; intpart--)
239
      *buf++= DIG_MAX;
240
  }
241
242
  if ((to->frac= frac))
243
  {
244
    int lastdigits= frac % DIG_PER_DEC1;
245
    for(frac/= DIG_PER_DEC1; frac; frac--)
246
      *buf++= DIG_MAX;
247
    if (lastdigits)
248
      *buf= frac_max[lastdigits - 1];
249
  }
250
}
251
252
253
static dec1 *remove_leading_zeroes(decimal_t *from, int *intg_result)
254
{
255
  int intg= from->intg, i;
256
  dec1 *buf0= from->buf;
257
  i= ((intg - 1) % DIG_PER_DEC1) + 1;
258
  while (intg > 0 && *buf0 == 0)
259
  {
260
    intg-= i;
261
    i= DIG_PER_DEC1;
262
    buf0++;
263
  }
264
  if (intg > 0)
265
  {
266
    for (i= (intg - 1) % DIG_PER_DEC1; *buf0 < powers10[i--]; intg--) ;
267
    DBUG_ASSERT(intg > 0);
268
  }
269
  else
270
    intg=0;
271
  *intg_result= intg;
272
  return buf0;
273
}
274
275
276
/*
277
  Count actual length of fraction part (without ending zeroes)
278
279
  SYNOPSIS
280
    decimal_actual_fraction()
281
    from    number for processing
282
*/
283
284
int decimal_actual_fraction(decimal_t *from)
285
{
286
  int frac= from->frac, i;
287
  dec1 *buf0= from->buf + ROUND_UP(from->intg) + ROUND_UP(frac) - 1;
288
289
  if (frac == 0)
290
    return 0;
291
292
  i= ((frac - 1) % DIG_PER_DEC1 + 1);
293
  while (frac > 0 && *buf0 == 0)
294
  {
295
    frac-= i;
296
    i= DIG_PER_DEC1;
297
    buf0--;
298
  }
299
  if (frac > 0)
300
  {
301
    for (i= DIG_PER_DEC1 - ((frac - 1) % DIG_PER_DEC1); *buf0 % powers10[i++] == 0; frac--) {};
302
  }
303
  return frac;
304
}
305
306
307
/*
308
  Convert decimal to its printable string representation
309
310
  SYNOPSIS
311
    decimal2string()
312
      from            - value to convert
313
      to              - points to buffer where string representation
314
                        should be stored
315
      *to_len         - in:  size of to buffer
316
                        out: length of the actually written string
317
      fixed_precision - 0 if representation can be variable length and
318
                        fixed_decimals will not be checked in this case.
319
                        Put number as with fixed point position with this
320
                        number of digits (sign counted and decimal point is
321
                        counted)
322
      fixed_decimals  - number digits after point.
323
      filler          - character to fill gaps in case of fixed_precision > 0
324
325
  RETURN VALUE
326
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
327
*/
328
329
int decimal2string(decimal_t *from, char *to, int *to_len,
330
                   int fixed_precision, int fixed_decimals,
331
                   char filler)
332
{
333
  int len, intg, frac= from->frac, i, intg_len, frac_len, fill;
334
  /* number digits before decimal point */
335
  int fixed_intg= (fixed_precision ?
336
                   (fixed_precision - fixed_decimals) : 0);
337
  int error=E_DEC_OK;
338
  char *s=to;
339
  dec1 *buf, *buf0=from->buf, tmp;
340
341
  DBUG_ASSERT(*to_len >= 2+from->sign);
342
343
  /* removing leading zeroes */
344
  buf0= remove_leading_zeroes(from, &intg);
345
  if (unlikely(intg+frac==0))
346
  {
347
    intg=1;
348
    tmp=0;
349
    buf0=&tmp;
350
  }
351
352
  if (!(intg_len= fixed_precision ? fixed_intg : intg))
353
    intg_len= 1;
354
  frac_len= fixed_precision ? fixed_decimals : frac;
355
  len= from->sign + intg_len + test(frac) + frac_len;
356
  if (fixed_precision)
357
  {
358
    if (frac > fixed_decimals)
359
    {
360
      error= E_DEC_TRUNCATED;
361
      frac= fixed_decimals;
362
    }
363
    if (intg > fixed_intg)
364
    {
365
      error= E_DEC_OVERFLOW;
366
      intg= fixed_intg;
367
    }
368
  }
369
  else if (unlikely(len > --*to_len)) /* reserve one byte for \0 */
370
  {
371
    int j= len-*to_len;
372
    error= (frac && j <= frac + 1) ? E_DEC_TRUNCATED : E_DEC_OVERFLOW;
373
    if (frac && j >= frac + 1) j--;
374
    if (j > frac)
375
    {
376
      intg-= j-frac;
377
      frac= 0;
378
    }
379
    else
380
      frac-=j;
381
    len= from->sign + intg_len + test(frac) + frac_len;
382
  }
383
  *to_len=len;
384
  s[len]=0;
385
386
  if (from->sign)
387
    *s++='-';
388
389
  if (frac)
390
  {
391
    char *s1= s + intg_len;
392
    fill= frac_len - frac;
393
    buf=buf0+ROUND_UP(intg);
394
    *s1++='.';
395
    for (; frac>0; frac-=DIG_PER_DEC1)
396
    {
397
      dec1 x=*buf++;
398
      for (i=min(frac, DIG_PER_DEC1); i; i--)
399
      {
400
        dec1 y=x/DIG_MASK;
401
        *s1++='0'+(uchar)y;
402
        x-=y*DIG_MASK;
403
        x*=10;
404
      }
405
    }
406
    for(; fill; fill--)
407
      *s1++=filler;
408
  }
409
410
  fill= intg_len - intg;
411
  if (intg == 0)
412
    fill--; /* symbol 0 before digital point */
413
  for(; fill; fill--)
414
    *s++=filler;
415
  if (intg)
416
  {
417
    s+=intg;
418
    for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
419
    {
420
      dec1 x=*--buf;
421
      for (i=min(intg, DIG_PER_DEC1); i; i--)
422
      {
423
        dec1 y=x/10;
424
        *--s='0'+(uchar)(x-y*10);
425
        x=y;
426
      }
427
    }
428
  }
429
  else
430
    *s= '0';
431
  return error;
432
}
433
434
435
/*
436
  Return bounds of decimal digits in the number
437
438
  SYNOPSIS
439
    digits_bounds()
440
      from         - decimal number for processing
441
      start_result - index (from 0 ) of first decimal digits will
442
                     be written by this address
443
      end_result   - index of position just after last decimal digit
444
                     be written by this address
445
*/
446
447
static void digits_bounds(decimal_t *from, int *start_result, int *end_result)
448
{
449
  int start, stop, i;
450
  dec1 *buf_beg= from->buf;
451
  dec1 *end= from->buf + ROUND_UP(from->intg) + ROUND_UP(from->frac);
452
  dec1 *buf_end= end - 1;
453
454
  /* find non-zero digit from number begining */
455
  while (buf_beg < end && *buf_beg == 0)
456
    buf_beg++;
457
458
  if (buf_beg >= end)
459
  {
460
    /* it is zero */
461
    *start_result= *end_result= 0;
462
    return;
463
  }
464
465
  /* find non-zero decimal digit from number begining */
466
  if (buf_beg == from->buf && from->intg)
467
  {
468
    start= DIG_PER_DEC1 - (i= ((from->intg-1) % DIG_PER_DEC1 + 1));
469
    i--;
470
  }
471
  else
472
  {
473
    i= DIG_PER_DEC1 - 1;
474
    start= (int) ((buf_beg - from->buf) * DIG_PER_DEC1);
475
  }
476
  if (buf_beg < end)
477
    for (; *buf_beg < powers10[i--]; start++) ;
478
  *start_result= start; /* index of first decimal digit (from 0) */
479
480
  /* find non-zero digit at the end */
481
  while (buf_end > buf_beg  && *buf_end == 0)
482
    buf_end--;
483
  /* find non-zero decimal digit from the end */
484
  if (buf_end == end - 1 && from->frac)
485
  {
486
    stop= (int) (((buf_end - from->buf) * DIG_PER_DEC1 +
487
           (i= ((from->frac - 1) % DIG_PER_DEC1 + 1))));
488
    i= DIG_PER_DEC1 - i + 1;
489
  }
490
  else
491
  {
492
    stop= (int) ((buf_end - from->buf + 1) * DIG_PER_DEC1);
493
    i= 1;
494
  }
495
  for (; *buf_end % powers10[i++] == 0; stop--) {};
496
  *end_result= stop; /* index of position after last decimal digit (from 0) */
497
}
498
499
500
/*
501
  Left shift for alignment of data in buffer
502
503
  SYNOPSIS
504
    do_mini_left_shift()
505
    dec     pointer to decimal number which have to be shifted
506
    shift   number of decimal digits on which it should be shifted
507
    beg/end bounds of decimal digits (see digits_bounds())
508
509
  NOTE
510
    Result fitting in the buffer should be garanted.
511
    'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
512
*/
513
53.2.13 by Monty Taylor
Various static declares.
514
static void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
1 by brian
clean slate
515
{
516
  dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
517
  dec1 *end= dec->buf + ROUND_UP(last) - 1;
518
  int c_shift= DIG_PER_DEC1 - shift;
519
  DBUG_ASSERT(from >= dec->buf);
520
  DBUG_ASSERT(end < dec->buf + dec->len);
521
  if (beg % DIG_PER_DEC1 < shift)
522
    *(from - 1)= (*from) / powers10[c_shift];
523
  for(; from < end; from++)
524
    *from= ((*from % powers10[c_shift]) * powers10[shift] +
525
            (*(from + 1)) / powers10[c_shift]);
526
  *from= (*from % powers10[c_shift]) * powers10[shift];
527
}
528
529
530
/*
531
  Right shift for alignment of data in buffer
532
533
  SYNOPSIS
534
    do_mini_left_shift()
535
    dec     pointer to decimal number which have to be shifted
536
    shift   number of decimal digits on which it should be shifted
537
    beg/end bounds of decimal digits (see digits_bounds())
538
539
  NOTE
540
    Result fitting in the buffer should be garanted.
541
    'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
542
*/
543
53.2.13 by Monty Taylor
Various static declares.
544
static void do_mini_right_shift(decimal_t *dec, int shift, int beg, int last)
1 by brian
clean slate
545
{
546
  dec1 *from= dec->buf + ROUND_UP(last) - 1;
547
  dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1;
548
  int c_shift= DIG_PER_DEC1 - shift;
549
  DBUG_ASSERT(from < dec->buf + dec->len);
550
  DBUG_ASSERT(end >= dec->buf);
551
  if (DIG_PER_DEC1 - ((last - 1) % DIG_PER_DEC1 + 1) < shift)
552
    *(from + 1)= (*from % powers10[shift]) * powers10[c_shift];
553
  for(; from > end; from--)
554
    *from= (*from / powers10[shift] +
555
            (*(from - 1) % powers10[shift]) * powers10[c_shift]);
556
  *from= *from / powers10[shift];
557
}
558
559
560
/*
561
  Shift of decimal digits in given number (with rounding if it need)
562
563
  SYNOPSIS
564
    decimal_shift()
565
    dec       number to be shifted
566
    shift     number of decimal positions
567
              shift > 0 means shift to left shift
568
              shift < 0 meand right shift
569
  NOTE
570
    In fact it is multipling on 10^shift.
571
  RETURN
572
    E_DEC_OK          OK
573
    E_DEC_OVERFLOW    operation lead to overflow, number is untoched
574
    E_DEC_TRUNCATED   number was rounded to fit into buffer
575
*/
576
53.2.13 by Monty Taylor
Various static declares.
577
static int decimal_shift(decimal_t *dec, int shift)
1 by brian
clean slate
578
{
579
  /* index of first non zero digit (all indexes from 0) */
580
  int beg;
581
  /* index of position after last decimal digit */
582
  int end;
583
  /* index of digit position just after point */
584
  int point= ROUND_UP(dec->intg) * DIG_PER_DEC1;
585
  /* new point position */
586
  int new_point= point + shift;
587
  /* number of digits in result */
588
  int digits_int, digits_frac;
589
  /* length of result and new fraction in big digits*/
590
  int new_len, new_frac_len;
591
  /* return code */
592
  int err= E_DEC_OK;
593
  int new_front;
594
595
  if (shift == 0)
596
    return E_DEC_OK;
597
598
  digits_bounds(dec, &beg, &end);
599
600
  if (beg == end)
601
  {
602
    decimal_make_zero(dec);
603
    return E_DEC_OK;
604
  }
605
606
  digits_int= new_point - beg;
607
  set_if_bigger(digits_int, 0);
608
  digits_frac= end - new_point;
609
  set_if_bigger(digits_frac, 0);
610
611
  if ((new_len= ROUND_UP(digits_int) + (new_frac_len= ROUND_UP(digits_frac))) >
612
      dec->len)
613
  {
614
    int lack= new_len - dec->len;
615
    int diff;
616
617
    if (new_frac_len < lack)
618
      return E_DEC_OVERFLOW; /* lack more then we have in fraction */
619
620
    /* cat off fraction part to allow new number to fit in our buffer */
621
    err= E_DEC_TRUNCATED;
622
    new_frac_len-= lack;
623
    diff= digits_frac - (new_frac_len * DIG_PER_DEC1);
624
    /* Make rounding method as parameter? */
625
    decimal_round(dec, dec, end - point - diff, HALF_UP);
626
    end-= diff;
627
    digits_frac= new_frac_len * DIG_PER_DEC1;
628
629
    if (end <= beg)
630
    {
631
      /*
632
        we lost all digits (they will be shifted out of buffer), so we can
633
        just return 0
634
      */
635
      decimal_make_zero(dec);
636
      return E_DEC_TRUNCATED;
637
    }
638
  }
639
640
  if (shift % DIG_PER_DEC1)
641
  {
642
    int l_mini_shift, r_mini_shift, mini_shift;
643
    int do_left;
644
    /*
645
      Calculate left/right shift to align decimal digits inside our bug
646
      digits correctly
647
    */
648
    if (shift > 0)
649
    {
650
      l_mini_shift= shift % DIG_PER_DEC1;
651
      r_mini_shift= DIG_PER_DEC1 - l_mini_shift;
652
      /*
653
        It is left shift so prefer left shift, but if we have not place from
654
        left, we have to have it from right, because we checked length of
655
        result
656
      */
657
      do_left= l_mini_shift <= beg;
658
      DBUG_ASSERT(do_left || (dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
659
    }
660
    else
661
    {
662
      r_mini_shift= (-shift) % DIG_PER_DEC1;
663
      l_mini_shift= DIG_PER_DEC1 - r_mini_shift;
664
      /* see comment above */
665
      do_left= !((dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
666
      DBUG_ASSERT(!do_left || l_mini_shift <= beg);
667
    }
668
    if (do_left)
669
    {
670
      do_mini_left_shift(dec, l_mini_shift, beg, end);
671
      mini_shift=- l_mini_shift;
672
    }
673
    else
674
    {
675
      do_mini_right_shift(dec, r_mini_shift, beg, end);
676
      mini_shift= r_mini_shift;
677
    }
678
    new_point+= mini_shift;
679
    /*
680
      If number is shifted and correctly aligned in buffer we can
681
      finish
682
    */
683
    if (!(shift+= mini_shift) && (new_point - digits_int) < DIG_PER_DEC1)
684
    {
685
      dec->intg= digits_int;
686
      dec->frac= digits_frac;
687
      return err;                 /* already shifted as it should be */
688
    }
689
    beg+= mini_shift;
690
    end+= mini_shift;
691
  }
692
693
  /* if new 'decimal front' is in first digit, we do not need move digits */
694
  if ((new_front= (new_point - digits_int)) >= DIG_PER_DEC1 ||
695
      new_front < 0)
696
  {
697
    /* need to move digits */
698
    int d_shift;
699
    dec1 *to, *barier;
700
    if (new_front > 0)
701
    {
702
      /* move left */
703
      d_shift= new_front / DIG_PER_DEC1;
704
      to= dec->buf + (ROUND_UP(beg + 1) - 1 - d_shift);
705
      barier= dec->buf + (ROUND_UP(end) - 1 - d_shift);
706
      DBUG_ASSERT(to >= dec->buf);
707
      DBUG_ASSERT(barier + d_shift < dec->buf + dec->len);
708
      for(; to <= barier; to++)
709
        *to= *(to + d_shift);
710
      for(barier+= d_shift; to <= barier; to++)
711
        *to= 0;
712
      d_shift= -d_shift;
713
    }
714
    else
715
    {
716
      /* move right */
717
      d_shift= (1 - new_front) / DIG_PER_DEC1;
718
      to= dec->buf + ROUND_UP(end) - 1 + d_shift;
719
      barier= dec->buf + ROUND_UP(beg + 1) - 1 + d_shift;
720
      DBUG_ASSERT(to < dec->buf + dec->len);
721
      DBUG_ASSERT(barier - d_shift >= dec->buf);
722
      for(; to >= barier; to--)
723
        *to= *(to - d_shift);
724
      for(barier-= d_shift; to >= barier; to--)
725
        *to= 0;
726
    }
727
    d_shift*= DIG_PER_DEC1;
728
    beg+= d_shift;
729
    end+= d_shift;
730
    new_point+= d_shift;
731
  }
732
733
  /*
734
    If there are gaps then fill ren with 0.
735
736
    Only one of following 'for' loops will work becouse beg <= end
737
  */
738
  beg= ROUND_UP(beg + 1) - 1;
739
  end= ROUND_UP(end) - 1;
740
  DBUG_ASSERT(new_point >= 0);
741
  
742
  /* We don't want negative new_point below */
743
  if (new_point != 0)
744
    new_point= ROUND_UP(new_point) - 1;
745
746
  if (new_point > end)
747
  {
748
    do
749
    {
750
      dec->buf[new_point]=0;
751
    } while (--new_point > end);
752
  }
753
  else
754
  {
755
    for (; new_point < beg; new_point++)
756
      dec->buf[new_point]= 0;
757
  }
758
  dec->intg= digits_int;
759
  dec->frac= digits_frac;
760
  return err;
761
}
762
763
764
/*
765
  Convert string to decimal
766
767
  SYNOPSIS
768
    internal_str2decl()
769
      from    - value to convert. Doesn't have to be \0 terminated!
770
      to      - decimal where where the result will be stored
771
                to->buf and to->len must be set.
772
      end     - Pointer to pointer to end of string. Will on return be
773
		set to the char after the last used character
774
      fixed   - use to->intg, to->frac as limits for input number
775
776
  NOTE
777
    to->intg and to->frac can be modified even when fixed=1
778
    (but only decreased, in this case)
779
780
  RETURN VALUE
781
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_BAD_NUM/E_DEC_OOM
782
    In case of E_DEC_FATAL_ERROR *to is set to decimal zero
783
    (to make error handling easier)
784
*/
785
786
int
787
internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed)
788
{
789
  const char *s= from, *s1, *endp, *end_of_string= *end;
790
  int i, intg, frac, error, intg1, frac1;
791
  dec1 x,*buf;
792
  sanity(to);
793
794
  error= E_DEC_BAD_NUM;                         /* In case of bad number */
795
  while (s < end_of_string && my_isspace(&my_charset_latin1, *s))
796
    s++;
797
  if (s == end_of_string)
798
    goto fatal_error;
799
800
  if ((to->sign= (*s == '-')))
801
    s++;
802
  else if (*s == '+')
803
    s++;
804
805
  s1=s;
806
  while (s < end_of_string && my_isdigit(&my_charset_latin1, *s))
807
    s++;
808
  intg= (int) (s-s1);
809
  if (s < end_of_string && *s=='.')
810
  {
811
    endp= s+1;
812
    while (endp < end_of_string && my_isdigit(&my_charset_latin1, *endp))
813
      endp++;
814
    frac= (int) (endp - s - 1);
815
  }
816
  else
817
  {
818
    frac= 0;
819
    endp= s;
820
  }
821
822
  *end= (char*) endp;
823
824
  if (frac+intg == 0)
825
    goto fatal_error;
826
827
  error= 0;
828
  if (fixed)
829
  {
830
    if (frac > to->frac)
831
    {
832
      error=E_DEC_TRUNCATED;
833
      frac=to->frac;
834
    }
835
    if (intg > to->intg)
836
    {
837
      error=E_DEC_OVERFLOW;
838
      intg=to->intg;
839
    }
840
    intg1=ROUND_UP(intg);
841
    frac1=ROUND_UP(frac);
842
    if (intg1+frac1 > to->len)
843
    {
844
      error= E_DEC_OOM;
845
      goto fatal_error;
846
    }
847
  }
848
  else
849
  {
850
    intg1=ROUND_UP(intg);
851
    frac1=ROUND_UP(frac);
852
    FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
853
    if (unlikely(error))
854
    {
855
      frac=frac1*DIG_PER_DEC1;
856
      if (error == E_DEC_OVERFLOW)
857
        intg=intg1*DIG_PER_DEC1;
858
    }
859
  }
860
  /* Error is guranteed to be set here */
861
  to->intg=intg;
862
  to->frac=frac;
863
864
  buf=to->buf+intg1;
865
  s1=s;
866
867
  for (x=0, i=0; intg; intg--)
868
  {
869
    x+= (*--s - '0')*powers10[i];
870
871
    if (unlikely(++i == DIG_PER_DEC1))
872
    {
873
      *--buf=x;
874
      x=0;
875
      i=0;
876
    }
877
  }
878
  if (i)
879
    *--buf=x;
880
881
  buf=to->buf+intg1;
882
  for (x=0, i=0; frac; frac--)
883
  {
884
    x= (*++s1 - '0') + x*10;
885
886
    if (unlikely(++i == DIG_PER_DEC1))
887
    {
888
      *buf++=x;
889
      x=0;
890
      i=0;
891
    }
892
  }
893
  if (i)
894
    *buf=x*powers10[DIG_PER_DEC1-i];
895
896
  /* Handle exponent */
897
  if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
898
  {
899
    int str_error;
152 by Brian Aker
longlong replacement
900
    int64_t exponent= my_strtoll10(endp+1, (char**) &end_of_string,
1 by brian
clean slate
901
                                    &str_error);
902
903
    if (end_of_string != endp +1)               /* If at least one digit */
904
    {
905
      *end= (char*) end_of_string;
906
      if (str_error > 0)
907
      {
908
        error= E_DEC_BAD_NUM;
909
        goto fatal_error;
910
      }
911
      if (exponent > INT_MAX/2 || (str_error == 0 && exponent < 0))
912
      {
913
        error= E_DEC_OVERFLOW;
914
        goto fatal_error;
915
      }
916
      if (exponent < INT_MIN/2 && error != E_DEC_OVERFLOW)
917
      {
918
        error= E_DEC_TRUNCATED;
919
        goto fatal_error;
920
      }
921
      if (error != E_DEC_OVERFLOW)
922
        error= decimal_shift(to, (int) exponent);
923
    }
924
  }
925
  return error;
926
927
fatal_error:
928
  decimal_make_zero(to);
929
  return error;
930
}
931
932
933
/*
934
  Convert decimal to double
935
936
  SYNOPSIS
937
    decimal2double()
938
      from    - value to convert
939
      to      - result will be stored there
940
941
  RETURN VALUE
942
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
943
*/
944
945
int decimal2double(decimal_t *from, double *to)
946
{
947
  char strbuf[FLOATING_POINT_BUFFER], *end;
948
  int len= sizeof(strbuf);
949
  int rc, error;
950
951
  rc = decimal2string(from, strbuf, &len, 0, 0, 0);
952
  end= strbuf + len;
953
  
954
  DBUG_PRINT("info", ("interm.: %s", strbuf));
955
956
  *to= my_strtod(strbuf, &end, &error);
957
             
958
  DBUG_PRINT("info", ("result: %f (%lx)", *to, *(ulong *)to));
959
960
  return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
961
}
962
963
/*
964
  Convert double to decimal
965
966
  SYNOPSIS
967
    double2decimal()
968
      from    - value to convert
969
      to      - result will be stored there
970
971
  RETURN VALUE
972
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
973
*/
974
975
int double2decimal(double from, decimal_t *to)
976
{
977
  char buff[FLOATING_POINT_BUFFER], *end;
978
  int res;
979
  DBUG_ENTER("double2decimal");
980
  end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
981
  res= string2decimal(buff, to, &end);
982
  DBUG_PRINT("exit", ("res: %d", res));
983
  DBUG_RETURN(res);
984
}
985
986
151 by Brian Aker
Ulonglong to uint64_t
987
static int ull2dec(uint64_t from, decimal_t *to)
1 by brian
clean slate
988
{
989
  int intg1, error=E_DEC_OK;
151 by Brian Aker
Ulonglong to uint64_t
990
  uint64_t x=from;
1 by brian
clean slate
991
  dec1 *buf;
992
993
  sanity(to);
994
995
  for (intg1=1; from >= DIG_BASE; intg1++, from/=DIG_BASE) {};
996
  if (unlikely(intg1 > to->len))
997
  {
998
    intg1=to->len;
999
    error=E_DEC_OVERFLOW;
1000
  }
1001
  to->frac=0;
1002
  to->intg=intg1*DIG_PER_DEC1;
1003
1004
  for (buf=to->buf+intg1; intg1; intg1--)
1005
  {
151 by Brian Aker
Ulonglong to uint64_t
1006
    uint64_t y=x/DIG_BASE;
1 by brian
clean slate
1007
    *--buf=(dec1)(x-y*DIG_BASE);
1008
    x=y;
1009
  }
1010
  return error;
1011
}
1012
151 by Brian Aker
Ulonglong to uint64_t
1013
int uint64_t2decimal(uint64_t from, decimal_t *to)
1 by brian
clean slate
1014
{
1015
  to->sign=0;
1016
  return ull2dec(from, to);
1017
}
1018
152 by Brian Aker
longlong replacement
1019
int int64_t2decimal(int64_t from, decimal_t *to)
1 by brian
clean slate
1020
{
1021
  if ((to->sign= from < 0))
1022
    return ull2dec(-from, to);
1023
  return ull2dec(from, to);
1024
}
1025
151 by Brian Aker
Ulonglong to uint64_t
1026
int decimal2uint64_t(decimal_t *from, uint64_t *to)
1 by brian
clean slate
1027
{
1028
  dec1 *buf=from->buf;
151 by Brian Aker
Ulonglong to uint64_t
1029
  uint64_t x=0;
1 by brian
clean slate
1030
  int intg, frac;
1031
1032
  if (from->sign)
1033
  {
80.1.1 by Brian Aker
LL() cleanup
1034
      *to= 0ULL;
1 by brian
clean slate
1035
      return E_DEC_OVERFLOW;
1036
  }
1037
1038
  for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1039
  {
151 by Brian Aker
Ulonglong to uint64_t
1040
    uint64_t y=x;
1 by brian
clean slate
1041
    x=x*DIG_BASE + *buf++;
163 by Brian Aker
Merge Monty's code.
1042
    if (unlikely(y > ((uint64_t) UINT64_MAX/DIG_BASE) || x < y))
1 by brian
clean slate
1043
    {
163 by Brian Aker
Merge Monty's code.
1044
      *to=UINT64_MAX;
1 by brian
clean slate
1045
      return E_DEC_OVERFLOW;
1046
    }
1047
  }
1048
  *to=x;
1049
  for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1050
    if (*buf++)
1051
      return E_DEC_TRUNCATED;
1052
  return E_DEC_OK;
1053
}
1054
152 by Brian Aker
longlong replacement
1055
int decimal2int64_t(decimal_t *from, int64_t *to)
1 by brian
clean slate
1056
{
1057
  dec1 *buf=from->buf;
152 by Brian Aker
longlong replacement
1058
  int64_t x=0;
1 by brian
clean slate
1059
  int intg, frac;
1060
1061
  for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1062
  {
152 by Brian Aker
longlong replacement
1063
    int64_t y=x;
1 by brian
clean slate
1064
    /*
1065
      Attention: trick!
1066
      we're calculating -|from| instead of |from| here
163 by Brian Aker
Merge Monty's code.
1067
      because |INT64_MIN| > INT64_MAX
1 by brian
clean slate
1068
      so we can convert -9223372036854775808 correctly
1069
    */
1070
    x=x*DIG_BASE - *buf++;
163 by Brian Aker
Merge Monty's code.
1071
    if (unlikely(y < (INT64_MIN/DIG_BASE) || x > y))
1 by brian
clean slate
1072
    {
1073
      /*
1074
        the decimal is bigger than any possible integer
1075
        return border integer depending on the sign
1076
      */
163 by Brian Aker
Merge Monty's code.
1077
      *to= from->sign ? INT64_MIN : INT64_MAX;
1 by brian
clean slate
1078
      return E_DEC_OVERFLOW;
1079
    }
1080
  }
1081
  /* boundary case: 9223372036854775808 */
163 by Brian Aker
Merge Monty's code.
1082
  if (unlikely(from->sign==0 && x == INT64_MIN))
1 by brian
clean slate
1083
  {
163 by Brian Aker
Merge Monty's code.
1084
    *to= INT64_MAX;
1 by brian
clean slate
1085
    return E_DEC_OVERFLOW;
1086
  }
1087
1088
  *to=from->sign ? x : -x;
1089
  for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1090
    if (*buf++)
1091
      return E_DEC_TRUNCATED;
1092
  return E_DEC_OK;
1093
}
1094
1095
/*
1096
  Convert decimal to its binary fixed-length representation
1097
  two representations of the same length can be compared with memcmp
1098
  with the correct -1/0/+1 result
1099
1100
  SYNOPSIS
1101
    decimal2bin()
1102
      from    - value to convert
1103
      to      - points to buffer where string representation should be stored
1104
      precision/scale - see decimal_bin_size() below
1105
1106
  NOTE
1107
    the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1108
1109
  RETURN VALUE
1110
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1111
1112
  DESCRIPTION
1113
    for storage decimal numbers are converted to the "binary" format.
1114
1115
    This format has the following properties:
1116
      1. length of the binary representation depends on the {precision, scale}
1117
      as provided by the caller and NOT on the intg/frac of the decimal to
1118
      convert.
1119
      2. binary representations of the same {precision, scale} can be compared
1120
      with memcmp - with the same result as decimal_cmp() of the original
1121
      decimals (not taking into account possible precision loss during
1122
      conversion).
1123
1124
    This binary format is as follows:
1125
      1. First the number is converted to have a requested precision and scale.
1126
      2. Every full DIG_PER_DEC1 digits of intg part are stored in 4 bytes
1127
         as is
1128
      3. The first intg % DIG_PER_DEC1 digits are stored in the reduced
1129
         number of bytes (enough bytes to store this number of digits -
1130
         see dig2bytes)
1131
      4. same for frac - full decimal_digit_t's are stored as is,
1132
         the last frac % DIG_PER_DEC1 digits - in the reduced number of bytes.
1133
      5. If the number is negative - every byte is inversed.
1134
      5. The very first bit of the resulting byte array is inverted (because
1135
         memcmp compares unsigned bytes, see property 2 above)
1136
1137
    Example:
1138
1139
      1234567890.1234
1140
1141
    internally is represented as 3 decimal_digit_t's
1142
1143
      1 234567890 123400000
1144
1145
    (assuming we want a binary representation with precision=14, scale=4)
1146
    in hex it's
1147
1148
      00-00-00-01  0D-FB-38-D2  07-5A-EF-40
1149
1150
    now, middle decimal_digit_t is full - it stores 9 decimal digits. It goes
1151
    into binary representation as is:
1152
1153
1154
      ...........  0D-FB-38-D2 ............
1155
1156
    First decimal_digit_t has only one decimal digit. We can store one digit in
1157
    one byte, no need to waste four:
1158
1159
                01 0D-FB-38-D2 ............
1160
1161
    now, last digit. It's 123400000. We can store 1234 in two bytes:
1162
1163
                01 0D-FB-38-D2 04-D2
1164
1165
    So, we've packed 12 bytes number in 7 bytes.
1166
    And now we invert the highest bit to get the final result:
1167
1168
                81 0D FB 38 D2 04 D2
1169
1170
    And for -1234567890.1234 it would be
1171
1172
                7E F2 04 37 2D FB 2D
1173
*/
1174
int decimal2bin(decimal_t *from, uchar *to, int precision, int frac)
1175
{
1176
  dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1177
  int error=E_DEC_OK, intg=precision-frac,
1178
      isize1, intg1, intg1x, from_intg,
1179
      intg0=intg/DIG_PER_DEC1,
1180
      frac0=frac/DIG_PER_DEC1,
1181
      intg0x=intg-intg0*DIG_PER_DEC1,
1182
      frac0x=frac-frac0*DIG_PER_DEC1,
1183
      frac1=from->frac/DIG_PER_DEC1,
1184
      frac1x=from->frac-frac1*DIG_PER_DEC1,
1185
      isize0=intg0*sizeof(dec1)+dig2bytes[intg0x],
1186
      fsize0=frac0*sizeof(dec1)+dig2bytes[frac0x],
1187
      fsize1=frac1*sizeof(dec1)+dig2bytes[frac1x];
1188
  const int orig_isize0= isize0;
1189
  const int orig_fsize0= fsize0;
1190
  uchar *orig_to= to;
1191
1192
  buf1= remove_leading_zeroes(from, &from_intg);
1193
1194
  if (unlikely(from_intg+fsize1==0))
1195
  {
1196
    mask=0; /* just in case */
1197
    intg=1;
1198
    buf1=&mask;
1199
  }
1200
1201
  intg1=from_intg/DIG_PER_DEC1;
1202
  intg1x=from_intg-intg1*DIG_PER_DEC1;
1203
  isize1=intg1*sizeof(dec1)+dig2bytes[intg1x];
1204
1205
  if (intg < from_intg)
1206
  {
1207
    buf1+=intg1-intg0+(intg1x>0)-(intg0x>0);
1208
    intg1=intg0; intg1x=intg0x;
1209
    error=E_DEC_OVERFLOW;
1210
  }
1211
  else if (isize0 > isize1)
1212
  {
1213
    while (isize0-- > isize1)
1214
      *to++= (char)mask;
1215
  }
1216
  if (fsize0 < fsize1)
1217
  {
1218
    frac1=frac0; frac1x=frac0x;
1219
    error=E_DEC_TRUNCATED;
1220
  }
1221
  else if (fsize0 > fsize1 && frac1x)
1222
  {
1223
    if (frac0 == frac1)
1224
    {
1225
      frac1x=frac0x;
1226
      fsize0= fsize1;
1227
    }
1228
    else
1229
    {
1230
      frac1++;
1231
      frac1x=0;
1232
    }
1233
  }
1234
1235
  /* intg1x part */
1236
  if (intg1x)
1237
  {
1238
    int i=dig2bytes[intg1x];
1239
    dec1 x=(*buf1++ % powers10[intg1x]) ^ mask;
1240
    switch (i)
1241
    {
1242
      case 1: mi_int1store(to, x); break;
1243
      case 2: mi_int2store(to, x); break;
1244
      case 3: mi_int3store(to, x); break;
1245
      case 4: mi_int4store(to, x); break;
1246
      default: DBUG_ASSERT(0);
1247
    }
1248
    to+=i;
1249
  }
1250
1251
  /* intg1+frac1 part */
1252
  for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=sizeof(dec1))
1253
  {
1254
    dec1 x=*buf1++ ^ mask;
1255
    DBUG_ASSERT(sizeof(dec1) == 4);
1256
    mi_int4store(to, x);
1257
  }
1258
1259
  /* frac1x part */
1260
  if (frac1x)
1261
  {
1262
    dec1 x;
1263
    int i=dig2bytes[frac1x],
1264
        lim=(frac1 < frac0 ? DIG_PER_DEC1 : frac0x);
1265
    while (frac1x < lim && dig2bytes[frac1x] == i)
1266
      frac1x++;
1267
    x=(*buf1 / powers10[DIG_PER_DEC1 - frac1x]) ^ mask;
1268
    switch (i)
1269
    {
1270
      case 1: mi_int1store(to, x); break;
1271
      case 2: mi_int2store(to, x); break;
1272
      case 3: mi_int3store(to, x); break;
1273
      case 4: mi_int4store(to, x); break;
1274
      default: DBUG_ASSERT(0);
1275
    }
1276
    to+=i;
1277
  }
1278
  if (fsize0 > fsize1)
1279
  {
1280
    uchar *to_end= orig_to + orig_fsize0 + orig_isize0;
1281
1282
    while (fsize0-- > fsize1 && to < to_end)
1283
      *to++= (uchar)mask;
1284
  }
1285
  orig_to[0]^= 0x80;
1286
1287
  /* Check that we have written the whole decimal and nothing more */
1288
  DBUG_ASSERT(to == orig_to + orig_fsize0 + orig_isize0);
1289
  return error;
1290
}
1291
1292
/*
1293
  Restores decimal from its binary fixed-length representation
1294
1295
  SYNOPSIS
1296
    bin2decimal()
1297
      from    - value to convert
1298
      to      - result
1299
      precision/scale - see decimal_bin_size() below
1300
1301
  NOTE
1302
    see decimal2bin()
1303
    the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1304
1305
  RETURN VALUE
1306
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1307
*/
1308
1309
int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale)
1310
{
1311
  int error=E_DEC_OK, intg=precision-scale,
1312
      intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1313
      intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
1314
      intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
1315
  dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
1316
  const uchar *stop;
1317
  uchar *d_copy;
1318
  int bin_size= decimal_bin_size(precision, scale);
1319
1320
  sanity(to);
1321
  d_copy= (uchar*) my_alloca(bin_size);
1322
  memcpy(d_copy, from, bin_size);
1323
  d_copy[0]^= 0x80;
1324
  from= d_copy;
1325
1326
  FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
1327
  if (unlikely(error))
1328
  {
1329
    if (intg1 < intg0+(intg0x>0))
1330
    {
1331
      from+=dig2bytes[intg0x]+sizeof(dec1)*(intg0-intg1);
1332
      frac0=frac0x=intg0x=0;
1333
      intg0=intg1;
1334
    }
1335
    else
1336
    {
1337
      frac0x=0;
1338
      frac0=frac1;
1339
    }
1340
  }
1341
1342
  to->sign=(mask != 0);
1343
  to->intg=intg0*DIG_PER_DEC1+intg0x;
1344
  to->frac=frac0*DIG_PER_DEC1+frac0x;
1345
1346
  if (intg0x)
1347
  {
1348
    int i=dig2bytes[intg0x];
1349
    dec1 x= 0;
1350
    switch (i)
1351
    {
1352
      case 1: x=mi_sint1korr(from); break;
1353
      case 2: x=mi_sint2korr(from); break;
1354
      case 3: x=mi_sint3korr(from); break;
1355
      case 4: x=mi_sint4korr(from); break;
1356
      default: DBUG_ASSERT(0);
1357
    }
1358
    from+=i;
1359
    *buf=x ^ mask;
151 by Brian Aker
Ulonglong to uint64_t
1360
    if (((uint64_t)*buf) >= (uint64_t) powers10[intg0x+1])
1 by brian
clean slate
1361
      goto err;
1362
    if (buf > to->buf || *buf != 0)
1363
      buf++;
1364
    else
1365
      to->intg-=intg0x;
1366
  }
1367
  for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1368
  {
1369
    DBUG_ASSERT(sizeof(dec1) == 4);
1370
    *buf=mi_sint4korr(from) ^ mask;
1371
    if (((uint32)*buf) > DIG_MAX)
1372
      goto err;
1373
    if (buf > to->buf || *buf != 0)
1374
      buf++;
1375
    else
1376
      to->intg-=DIG_PER_DEC1;
1377
  }
1378
  DBUG_ASSERT(to->intg >=0);
1379
  for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1380
  {
1381
    DBUG_ASSERT(sizeof(dec1) == 4);
1382
    *buf=mi_sint4korr(from) ^ mask;
1383
    if (((uint32)*buf) > DIG_MAX)
1384
      goto err;
1385
    buf++;
1386
  }
1387
  if (frac0x)
1388
  {
1389
    int i=dig2bytes[frac0x];
1390
    dec1 x= 0;
1391
    switch (i)
1392
    {
1393
      case 1: x=mi_sint1korr(from); break;
1394
      case 2: x=mi_sint2korr(from); break;
1395
      case 3: x=mi_sint3korr(from); break;
1396
      case 4: x=mi_sint4korr(from); break;
1397
      default: DBUG_ASSERT(0);
1398
    }
1399
    *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
1400
    if (((uint32)*buf) > DIG_MAX)
1401
      goto err;
1402
    buf++;
1403
  }
1404
  my_afree(d_copy);
1405
  return error;
1406
1407
err:
1408
  my_afree(d_copy);
1409
  decimal_make_zero(((decimal_t*) to));
1410
  return(E_DEC_BAD_NUM);
1411
}
1412
1413
/*
1414
  Returns the size of array to hold a decimal with given precision and scale
1415
1416
  RETURN VALUE
1417
    size in dec1
1418
    (multiply by sizeof(dec1) to get the size if bytes)
1419
*/
1420
1421
int decimal_size(int precision, int scale)
1422
{
1423
  DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
1424
  return ROUND_UP(precision-scale)+ROUND_UP(scale);
1425
}
1426
1427
/*
1428
  Returns the size of array to hold a binary representation of a decimal
1429
1430
  RETURN VALUE
1431
    size in bytes
1432
*/
1433
1434
int decimal_bin_size(int precision, int scale)
1435
{
1436
  int intg=precision-scale,
1437
      intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1438
      intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1;
1439
1440
  DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
1441
  return intg0*sizeof(dec1)+dig2bytes[intg0x]+
1442
         frac0*sizeof(dec1)+dig2bytes[frac0x];
1443
}
1444
1445
/*
1446
  Rounds the decimal to "scale" digits
1447
1448
  SYNOPSIS
1449
    decimal_round()
1450
      from    - decimal to round,
1451
      to      - result buffer. from==to is allowed
1452
      scale   - to what position to round. can be negative!
1453
      mode    - round to nearest even or truncate
1454
1455
  NOTES
1456
    scale can be negative !
1457
    one TRUNCATED error (line XXX below) isn't treated very logical :(
1458
1459
  RETURN VALUE
1460
    E_DEC_OK/E_DEC_TRUNCATED
1461
*/
1462
1463
int
1464
decimal_round(decimal_t *from, decimal_t *to, int scale,
1465
              decimal_round_mode mode)
1466
{
1467
  int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
1468
      frac1=ROUND_UP(from->frac), round_digit= 0,
1469
      intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len,
1470
      intg1=ROUND_UP(from->intg +
1471
                     (((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX)));
1472
  dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
1473
  int first_dig;
1474
1475
  sanity(to);
1476
1477
  switch (mode) {
1478
  case HALF_UP:
1479
  case HALF_EVEN:       round_digit=5; break;
1480
  case CEILING:         round_digit= from->sign ? 10 : 0; break;
1481
  case FLOOR:           round_digit= from->sign ? 0 : 10; break;
1482
  case TRUNCATE:        round_digit=10; break;
1483
  default: DBUG_ASSERT(0);
1484
  }
1485
1486
  if (unlikely(frac0+intg0 > len))
1487
  {
1488
    frac0=len-intg0;
1489
    scale=frac0*DIG_PER_DEC1;
1490
    error=E_DEC_TRUNCATED;
1491
  }
1492
1493
  if (scale+from->intg < 0)
1494
  {
1495
    decimal_make_zero(to);
1496
    return E_DEC_OK;
1497
  }
1498
1499
  if (to != from || intg1>intg0)
1500
  {
1501
    dec1 *p0= buf0+intg0+max(frac1, frac0);
1502
    dec1 *p1= buf1+intg1+max(frac1, frac0);
1503
1504
    while (buf0 < p0)
1505
      *(--p1) = *(--p0);
1506
    if (unlikely(intg1 > intg0))
1507
      to->buf[0]= 0;
1508
1509
    intg0= intg1;
1510
    buf0=to->buf;
1511
    buf1=to->buf;
1512
    to->sign=from->sign;
1513
    to->intg=min(intg0, len)*DIG_PER_DEC1;
1514
  }
1515
1516
  if (frac0 > frac1)
1517
  {
1518
    buf1+=intg0+frac1;
1519
    while (frac0-- > frac1)
1520
      *buf1++=0;
1521
    goto done;
1522
  }
1523
1524
  if (scale >= from->frac)
1525
    goto done; /* nothing to do */
1526
1527
  buf0+=intg0+frac0-1;
1528
  buf1+=intg0+frac0-1;
1529
  if (scale == frac0*DIG_PER_DEC1)
1530
  {
163 by Brian Aker
Merge Monty's code.
1531
    int do_inc= false;
1 by brian
clean slate
1532
    DBUG_ASSERT(frac0+intg0 >= 0);
1533
    switch (round_digit) {
1534
    case 0:
1535
    {
1536
      dec1 *p0= buf0 + (frac1-frac0);
1537
      for (; p0 > buf0; p0--)
1538
      {
1539
        if (*p0)
1540
        {
163 by Brian Aker
Merge Monty's code.
1541
          do_inc= true;
1 by brian
clean slate
1542
          break;
1543
        }
1544
      }
1545
      break;
1546
    }
1547
    case 5:
1548
    {
1549
      x= buf0[1]/DIG_MASK;
1550
      do_inc= (x>5) || ((x == 5) &&
1551
                        (mode == HALF_UP || (frac0+intg0 > 0 && *buf0 & 1)));
1552
      break;
1553
    }
1554
    default:
1555
      break;
1556
    }
1557
    if (do_inc)
1558
    {
1559
      if (frac0+intg0>0)
1560
        (*buf1)++;
1561
      else
1562
        *(++buf1)=DIG_BASE;
1563
    }
1564
    else if (frac0+intg0==0)
1565
    {
1566
      decimal_make_zero(to);
1567
      return E_DEC_OK;
1568
    }
1569
  }
1570
  else
1571
  {
1572
    /* TODO - fix this code as it won't work for CEILING mode */
1573
    int pos=frac0*DIG_PER_DEC1-scale-1;
1574
    DBUG_ASSERT(frac0+intg0 > 0);
1575
    x=*buf1 / powers10[pos];
1576
    y=x % 10;
1577
    if (y > round_digit ||
1578
        (round_digit == 5 && y == 5 && (mode == HALF_UP || (x/10) & 1)))
1579
      x+=10;
1580
    *buf1=powers10[pos]*(x-y);
1581
  }
1582
  /*
1583
    In case we're rounding e.g. 1.5e9 to 2.0e9, the decimal_digit_t's inside
1584
    the buffer are as follows.
1585
1586
    Before <1, 5e8>
1587
    After  <2, 5e8>
1588
1589
    Hence we need to set the 2nd field to 0.
1590
    The same holds if we round 1.5e-9 to 2e-9.
1591
   */
1592
  if (frac0 < frac1)
1593
  {
1594
    dec1 *buf= to->buf + ((scale == 0 && intg0 == 0) ? 1 : intg0 + frac0);
1595
    dec1 *end= to->buf + len;
1596
1597
    while (buf < end)
1598
      *buf++=0;
1599
  }
1600
  if (*buf1 >= DIG_BASE)
1601
  {
1602
    carry=1;
1603
    *buf1-=DIG_BASE;
1604
    while (carry && --buf1 >= to->buf)
1605
      ADD(*buf1, *buf1, 0, carry);
1606
    if (unlikely(carry))
1607
    {
1608
      /* shifting the number to create space for new digit */
1609
      if (frac0+intg0 >= len)
1610
      {
1611
        frac0--;
1612
        scale=frac0*DIG_PER_DEC1;
1613
        error=E_DEC_TRUNCATED; /* XXX */
1614
      }
1615
      for (buf1=to->buf+intg0+max(frac0,0); buf1 > to->buf; buf1--)
1616
      {
1617
        buf1[0]=buf1[-1];
1618
      }
1619
      *buf1=1;
1620
      to->intg++;
1621
    }
1622
  }
1623
  else
1624
  {
1625
    for (;;)
1626
    {
1627
      if (likely(*buf1))
1628
        break;
1629
      if (buf1-- == to->buf)
1630
      {
1631
        /* making 'zero' with the proper scale */
1632
        dec1 *p0= to->buf + frac0 + 1;
1633
        to->intg=1;
1634
        to->frac= max(scale, 0);
1635
        to->sign= 0;
1636
        for (buf1= to->buf; buf1<p0; buf1++)
1637
          *buf1= 0;
1638
        return E_DEC_OK;
1639
      }
1640
    }
1641
  }
1642
1643
  /* Here we  check 999.9 -> 1000 case when we need to increase intg */
1644
  first_dig= to->intg % DIG_PER_DEC1;
1645
  if (first_dig && (*buf1 >= powers10[first_dig]))
1646
    to->intg++;
1647
1648
  if (scale<0)
1649
    scale=0;
1650
1651
done:
1652
  to->frac=scale;
1653
  return error;
1654
}
1655
1656
/*
1657
  Returns the size of the result of the operation
1658
1659
  SYNOPSIS
1660
    decimal_result_size()
1661
      from1   - operand of the unary operation or first operand of the
1662
                binary operation
1663
      from2   - second operand of the binary operation
1664
      op      - operation. one char '+', '-', '*', '/' are allowed
1665
                others may be added later
1666
      param   - extra param to the operation. unused for '+', '-', '*'
1667
                scale increment for '/'
1668
1669
  NOTE
1670
    returned valued may be larger than the actual buffer requred
1671
    in the operation, as decimal_result_size, by design, operates on
1672
    precision/scale values only and not on the actual decimal number
1673
1674
  RETURN VALUE
1675
    size of to->buf array in dec1 elements. to get size in bytes
1676
    multiply by sizeof(dec1)
1677
*/
1678
1679
int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param)
1680
{
1681
  switch (op) {
1682
  case '-':
1683
    return ROUND_UP(max(from1->intg, from2->intg)) +
1684
           ROUND_UP(max(from1->frac, from2->frac));
1685
  case '+':
1686
    return ROUND_UP(max(from1->intg, from2->intg)+1) +
1687
           ROUND_UP(max(from1->frac, from2->frac));
1688
  case '*':
1689
    return ROUND_UP(from1->intg+from2->intg)+
1690
           ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
1691
  case '/':
1692
    return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param);
1693
  default: DBUG_ASSERT(0);
1694
  }
1695
  return -1; /* shut up the warning */
1696
}
1697
1698
static int do_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
1699
{
1700
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1701
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1702
      frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
1703
  dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
1704
1705
  sanity(to);
1706
1707
  /* is there a need for extra word because of carry ? */
1708
  x=intg1 > intg2 ? from1->buf[0] :
1709
    intg2 > intg1 ? from2->buf[0] :
1710
    from1->buf[0] + from2->buf[0] ;
1711
  if (unlikely(x > DIG_MAX-1)) /* yes, there is */
1712
  {
1713
    intg0++;
1714
    to->buf[0]=0; /* safety */
1715
  }
1716
1717
  FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
1718
  if (unlikely(error == E_DEC_OVERFLOW))
1719
  {
1720
    max_decimal(to->len * DIG_PER_DEC1, 0, to);
1721
    return error;
1722
  }
1723
1724
  buf0=to->buf+intg0+frac0;
1725
1726
  to->sign=from1->sign;
1727
  to->frac=max(from1->frac, from2->frac);
1728
  to->intg=intg0*DIG_PER_DEC1;
1729
  if (unlikely(error))
1730
  {
1731
    set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
1732
    set_if_smaller(frac1, frac0);
1733
    set_if_smaller(frac2, frac0);
1734
    set_if_smaller(intg1, intg0);
1735
    set_if_smaller(intg2, intg0);
1736
  }
1737
1738
  /* part 1 - max(frac) ... min (frac) */
1739
  if (frac1 > frac2)
1740
  {
1741
    buf1=from1->buf+intg1+frac1;
1742
    stop=from1->buf+intg1+frac2;
1743
    buf2=from2->buf+intg2+frac2;
1744
    stop2=from1->buf+(intg1 > intg2 ? intg1-intg2 : 0);
1745
  }
1746
  else
1747
  {
1748
    buf1=from2->buf+intg2+frac2;
1749
    stop=from2->buf+intg2+frac1;
1750
    buf2=from1->buf+intg1+frac1;
1751
    stop2=from2->buf+(intg2 > intg1 ? intg2-intg1 : 0);
1752
  }
1753
  while (buf1 > stop)
1754
    *--buf0=*--buf1;
1755
1756
  /* part 2 - min(frac) ... min(intg) */
1757
  carry=0;
1758
  while (buf1 > stop2)
1759
  {
1760
    ADD(*--buf0, *--buf1, *--buf2, carry);
1761
  }
1762
1763
  /* part 3 - min(intg) ... max(intg) */
1764
  buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
1765
                        ((stop=from2->buf)+intg2-intg1) ;
1766
  while (buf1 > stop)
1767
  {
1768
    ADD(*--buf0, *--buf1, 0, carry);
1769
  }
1770
1771
  if (unlikely(carry))
1772
    *--buf0=1;
1773
  DBUG_ASSERT(buf0 == to->buf || buf0 == to->buf+1);
1774
1775
  return error;
1776
}
1777
1778
/* to=from1-from2.
1779
   if to==0, return -1/0/+1 - the result of the comparison */
1780
static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
1781
{
1782
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1783
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
1784
  int frac0=max(frac1, frac2), error;
1785
  dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
1786
1787
  /* let carry:=1 if from2 > from1 */
1788
  start1=buf1=from1->buf; stop1=buf1+intg1;
1789
  start2=buf2=from2->buf; stop2=buf2+intg2;
1790
  if (unlikely(*buf1 == 0))
1791
  {
1792
    while (buf1 < stop1 && *buf1 == 0)
1793
      buf1++;
1794
    start1=buf1;
1795
    intg1= (int) (stop1-buf1);
1796
  }
1797
  if (unlikely(*buf2 == 0))
1798
  {
1799
    while (buf2 < stop2 && *buf2 == 0)
1800
      buf2++;
1801
    start2=buf2;
1802
    intg2= (int) (stop2-buf2);
1803
  }
1804
  if (intg2 > intg1)
1805
    carry=1;
1806
  else if (intg2 == intg1)
1807
  {
1808
    dec1 *end1= stop1 + (frac1 - 1);
1809
    dec1 *end2= stop2 + (frac2 - 1);
1810
    while (unlikely((buf1 <= end1) && (*end1 == 0)))
1811
      end1--;
1812
    while (unlikely((buf2 <= end2) && (*end2 == 0)))
1813
      end2--;
1814
    frac1= (int) (end1 - stop1) + 1;
1815
    frac2= (int) (end2 - stop2) + 1;
1816
    while (buf1 <=end1 && buf2 <= end2 && *buf1 == *buf2)
1817
      buf1++, buf2++;
1818
    if (buf1 <= end1)
1819
    {
1820
      if (buf2 <= end2)
1821
        carry= *buf2 > *buf1;
1822
      else
1823
        carry= 0;
1824
    }
1825
    else
1826
    {
1827
      if (buf2 <= end2)
1828
        carry=1;
1829
      else /* short-circuit everything: from1 == from2 */
1830
      {
1831
        if (to == 0) /* decimal_cmp() */
1832
          return 0;
1833
        decimal_make_zero(to);
1834
        return E_DEC_OK;
1835
      }
1836
    }
1837
  }
1838
1839
  if (to == 0) /* decimal_cmp() */
1840
    return carry == from1->sign ? 1 : -1;
1841
1842
  sanity(to);
1843
1844
  to->sign=from1->sign;
1845
1846
  /* ensure that always from1 > from2 (and intg1 >= intg2) */
1847
  if (carry)
1848
  {
1849
    swap_variables(decimal_t *,from1,from1);
1850
    swap_variables(dec1 *,start1, start2);
1851
    swap_variables(int,intg1,intg2);
1852
    swap_variables(int,frac1,frac2);
1853
    to->sign= 1 - to->sign;
1854
  }
1855
1856
  FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
1857
  buf0=to->buf+intg1+frac0;
1858
1859
  to->frac=max(from1->frac, from2->frac);
1860
  to->intg=intg1*DIG_PER_DEC1;
1861
  if (unlikely(error))
1862
  {
1863
    set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
1864
    set_if_smaller(frac1, frac0);
1865
    set_if_smaller(frac2, frac0);
1866
    set_if_smaller(intg2, intg1);
1867
  }
1868
  carry=0;
1869
1870
  /* part 1 - max(frac) ... min (frac) */
1871
  if (frac1 > frac2)
1872
  {
1873
    buf1=start1+intg1+frac1;
1874
    stop1=start1+intg1+frac2;
1875
    buf2=start2+intg2+frac2;
1876
    while (frac0-- > frac1)
1877
      *--buf0=0;
1878
    while (buf1 > stop1)
1879
      *--buf0=*--buf1;
1880
  }
1881
  else
1882
  {
1883
    buf1=start1+intg1+frac1;
1884
    buf2=start2+intg2+frac2;
1885
    stop2=start2+intg2+frac1;
1886
    while (frac0-- > frac2)
1887
      *--buf0=0;
1888
    while (buf2 > stop2)
1889
    {
1890
      SUB(*--buf0, 0, *--buf2, carry);
1891
    }
1892
  }
1893
1894
  /* part 2 - min(frac) ... intg2 */
1895
  while (buf2 > start2)
1896
  {
1897
    SUB(*--buf0, *--buf1, *--buf2, carry);
1898
  }
1899
1900
  /* part 3 - intg2 ... intg1 */
1901
  while (carry && buf1 > start1)
1902
  {
1903
    SUB(*--buf0, *--buf1, 0, carry);
1904
  }
1905
1906
  while (buf1 > start1)
1907
    *--buf0=*--buf1;
1908
1909
  while (buf0 > to->buf)
1910
    *--buf0=0;
1911
1912
  return error;
1913
}
1914
1915
int decimal_intg(decimal_t *from)
1916
{
1917
  int res;
1918
  dec1 *tmp_res;
1919
  tmp_res= remove_leading_zeroes(from, &res);
1920
  return res;
1921
}
1922
1923
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
1924
{
1925
  if (likely(from1->sign == from2->sign))
1926
    return do_add(from1, from2, to);
1927
  return do_sub(from1, from2, to);
1928
}
1929
1930
int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
1931
{
1932
  if (likely(from1->sign == from2->sign))
1933
    return do_sub(from1, from2, to);
1934
  return do_add(from1, from2, to);
1935
}
1936
1937
int decimal_cmp(decimal_t *from1, decimal_t *from2)
1938
{
1939
  if (likely(from1->sign == from2->sign))
1940
    return do_sub(from1, from2, 0);
1941
  return from1->sign > from2->sign ? -1 : 1;
1942
}
1943
1944
int decimal_is_zero(decimal_t *from)
1945
{
1946
  dec1 *buf1=from->buf,
1947
       *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
1948
  while (buf1 < end)
1949
    if (*buf1++)
1950
      return 0;
1951
  return 1;
1952
}
1953
1954
/*
1955
  multiply two decimals
1956
1957
  SYNOPSIS
1958
    decimal_mul()
1959
      from1, from2 - factors
1960
      to      - product
1961
1962
  RETURN VALUE
1963
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
1964
1965
  NOTES
1966
    in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
1967
    and 63-digit number will take only 7 dec1 words (basically a 7-digit
1968
    "base 999999999" number).  Thus there's no need in fast multiplication
1969
    algorithms, 7-digit numbers can be multiplied with a naive O(n*n)
1970
    method.
1971
1972
    XXX if this library is to be used with huge numbers of thousands of
1973
    digits, fast multiplication must be implemented.
1974
*/
1975
int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to)
1976
{
1977
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1978
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1979
      intg0=ROUND_UP(from1->intg+from2->intg),
1980
      frac0=frac1+frac2, error, i, j, d_to_move;
1981
  dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
1982
       *start2, *stop2, *stop1, *start0, carry;
1983
1984
  sanity(to);
1985
1986
  i=intg0;
1987
  j=frac0;
1988
  FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
1989
  to->sign=from1->sign != from2->sign;
1990
  to->frac=from1->frac+from2->frac;
1991
  to->intg=intg0*DIG_PER_DEC1;
1992
1993
  if (unlikely(error))
1994
  {
1995
    set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
1996
    set_if_smaller(to->intg, intg0*DIG_PER_DEC1);
1997
    if (unlikely(i > intg0))
1998
    {
1999
      i-=intg0;
2000
      j=i >> 1;
2001
      intg1-= j;
2002
      intg2-=i-j;
2003
      frac1=frac2=0; /* frac0 is already 0 here */
2004
    }
2005
    else
2006
    {
2007
      j-=frac0;
2008
      i=j >> 1;
2009
      frac1-= i;
2010
      frac2-=j-i;
2011
    }
2012
  }
2013
  start0=to->buf+intg0+frac0-1;
2014
  start2=buf2+frac2-1;
2015
  stop1=buf1-intg1;
2016
  stop2=buf2-intg2;
2017
2018
  bzero(to->buf, (intg0+frac0)*sizeof(dec1));
2019
2020
  for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
2021
  {
2022
    carry=0;
2023
    for (buf0=start0, buf2=start2; buf2 >= stop2; buf2--, buf0--)
2024
    {
2025
      dec1 hi, lo;
2026
      dec2 p= ((dec2)*buf1) * ((dec2)*buf2);
2027
      hi=(dec1)(p/DIG_BASE);
2028
      lo=(dec1)(p-((dec2)hi)*DIG_BASE);
2029
      ADD2(*buf0, *buf0, lo, carry);
2030
      carry+=hi;
2031
    }
2032
    if (carry)
2033
    {
2034
      if (buf0 < to->buf)
2035
        return E_DEC_OVERFLOW;
2036
      ADD2(*buf0, *buf0, 0, carry);
2037
    }
2038
    for (buf0--; carry; buf0--)
2039
    {
2040
      if (buf0 < to->buf)
2041
        return E_DEC_OVERFLOW;
2042
      ADD(*buf0, *buf0, 0, carry);
2043
    }
2044
  }
2045
2046
  /* Now we have to check for -0.000 case */
2047
  if (to->sign)
2048
  {
2049
    dec1 *buf= to->buf;
2050
    dec1 *end= to->buf + intg0 + frac0;
2051
    DBUG_ASSERT(buf != end);
2052
    for (;;)
2053
    {
2054
      if (*buf)
2055
        break;
2056
      if (++buf == end)
2057
      {
2058
        /* We got decimal zero */
2059
        decimal_make_zero(to);
2060
        break;
2061
      }
2062
    }
2063
  }
2064
  buf1= to->buf;
2065
  d_to_move= intg0 + ROUND_UP(to->frac);
2066
  while (!*buf1 && (to->intg > DIG_PER_DEC1))
2067
  {
2068
    buf1++;
2069
    to->intg-= DIG_PER_DEC1;
2070
    d_to_move--;
2071
  }
2072
  if (to->buf < buf1)
2073
  {
2074
    dec1 *cur_d= to->buf;
2075
    for (; d_to_move--; cur_d++, buf1++)
2076
      *cur_d= *buf1;
2077
  }
2078
  return error;
2079
}
2080
2081
/*
2082
  naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2083
  it's ok for short numbers
2084
  also we're using alloca() to allocate a temporary buffer
2085
2086
  XXX if this library is to be used with huge numbers of thousands of
2087
  digits, fast division must be implemented and alloca should be
2088
  changed to malloc (or at least fallback to malloc if alloca() fails)
2089
  but then, decimal_mul() should be rewritten too :(
2090
*/
2091
static int do_div_mod(decimal_t *from1, decimal_t *from2,
2092
                       decimal_t *to, decimal_t *mod, int scale_incr)
2093
{
2094
  int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2095
      frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2096
      error= 0, i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2097
  dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2098
       *start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
2099
  dec2 norm_factor, x, guess, y;
2100
2101
  if (mod)
2102
    to=mod;
2103
2104
  sanity(to);
2105
2106
  /* removing all the leading zeroes */
2107
  i= ((prec2 - 1) % DIG_PER_DEC1) + 1;
2108
  while (prec2 > 0 && *buf2 == 0)
2109
  {
2110
    prec2-= i;
2111
    i= DIG_PER_DEC1;
2112
    buf2++;
2113
  }
2114
  if (prec2 <= 0) /* short-circuit everything: from2 == 0 */
2115
    return E_DEC_DIV_ZERO;
2116
  for (i= (prec2 - 1) % DIG_PER_DEC1; *buf2 < powers10[i--]; prec2--) ;
2117
  DBUG_ASSERT(prec2 > 0);
2118
2119
  i=((prec1-1) % DIG_PER_DEC1)+1;
2120
  while (prec1 > 0 && *buf1 == 0)
2121
  {
2122
    prec1-=i;
2123
    i=DIG_PER_DEC1;
2124
    buf1++;
2125
  }
2126
  if (prec1 <= 0)
2127
  { /* short-circuit everything: from1 == 0 */
2128
    decimal_make_zero(to);
2129
    return E_DEC_OK;
2130
  }
2131
  for (i=(prec1-1) % DIG_PER_DEC1; *buf1 < powers10[i--]; prec1--) ;
2132
  DBUG_ASSERT(prec1 > 0);
2133
2134
  /* let's fix scale_incr, taking into account frac1,frac2 increase */
2135
  if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0)
2136
    scale_incr=0;
2137
2138
  dintg=(prec1-frac1)-(prec2-frac2)+(*buf1 >= *buf2);
2139
  if (dintg < 0)
2140
  {
2141
    dintg/=DIG_PER_DEC1;
2142
    intg0=0;
2143
  }
2144
  else
2145
    intg0=ROUND_UP(dintg);
2146
  if (mod)
2147
  {
2148
    /* we're calculating N1 % N2.
2149
       The result will have
2150
         frac=max(frac1, frac2), as for subtraction
2151
         intg=intg2
2152
    */
2153
    to->sign=from1->sign;
2154
    to->frac=max(from1->frac, from2->frac);
2155
    frac0=0;
2156
  }
2157
  else
2158
  {
2159
    /*
2160
      we're calculating N1/N2. N1 is in the buf1, has prec1 digits
2161
      N2 is in the buf2, has prec2 digits. Scales are frac1 and
2162
      frac2 accordingly.
2163
      Thus, the result will have
2164
         frac = ROUND_UP(frac1+frac2+scale_incr)
2165
      and
2166
         intg = (prec1-frac1) - (prec2-frac2) + 1
2167
         prec = intg+frac
2168
    */
2169
    frac0=ROUND_UP(frac1+frac2+scale_incr);
2170
    FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2171
    to->sign=from1->sign != from2->sign;
2172
    to->intg=intg0*DIG_PER_DEC1;
2173
    to->frac=frac0*DIG_PER_DEC1;
2174
  }
2175
  buf0=to->buf;
2176
  stop0=buf0+intg0+frac0;
2177
  if (likely(div_mod))
2178
    while (dintg++ < 0)
2179
      *buf0++=0;
2180
2181
  len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1;
2182
  set_if_bigger(len1, 3);
2183
  if (!(tmp1=(dec1 *)my_alloca(len1*sizeof(dec1))))
2184
    return E_DEC_OOM;
2185
  memcpy(tmp1, buf1, i*sizeof(dec1));
2186
  bzero(tmp1+i, (len1-i)*sizeof(dec1));
2187
2188
  start1=tmp1;
2189
  stop1=start1+len1;
2190
  start2=buf2;
2191
  stop2=buf2+ROUND_UP(prec2)-1;
2192
2193
  /* removing end zeroes */
2194
  while (*stop2 == 0 && stop2 >= start2)
2195
    stop2--;
2196
  len2= (int) (stop2++ - start2);
2197
2198
  /*
2199
    calculating norm2 (normalized *start2) - we need *start2 to be large
2200
    (at least > DIG_BASE/2), but unlike Knuth's Alg. D we don't want to
2201
    normalize input numbers (as we don't make a copy of the divisor).
2202
    Thus we normalize first dec1 of buf2 only, and we'll normalize *start1
2203
    on the fly for the purpose of guesstimation only.
2204
    It's also faster, as we're saving on normalization of buf2
2205
  */
2206
  norm_factor=DIG_BASE/(*start2+1);
2207
  norm2=(dec1)(norm_factor*start2[0]);
2208
  if (likely(len2>0))
2209
    norm2+=(dec1)(norm_factor*start2[1]/DIG_BASE);
2210
2211
  if (*start1 < *start2)
2212
    dcarry=*start1++;
2213
  else
2214
    dcarry=0;
2215
2216
  /* main loop */
2217
  for (; buf0 < stop0; buf0++)
2218
  {
2219
    /* short-circuit, if possible */
2220
    if (unlikely(dcarry == 0 && *start1 < *start2))
2221
      guess=0;
2222
    else
2223
    {
2224
      /* D3: make a guess */
2225
      x=start1[0]+((dec2)dcarry)*DIG_BASE;
2226
      y=start1[1];
2227
      guess=(norm_factor*x+norm_factor*y/DIG_BASE)/norm2;
2228
      if (unlikely(guess >= DIG_BASE))
2229
        guess=DIG_BASE-1;
2230
      if (likely(len2>0))
2231
      {
2232
        /* hmm, this is a suspicious trick - I removed normalization here */
2233
        if (start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y)
2234
          guess--;
2235
        if (unlikely(start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y))
2236
          guess--;
2237
        DBUG_ASSERT(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
2238
      }
2239
2240
      /* D4: multiply and subtract */
2241
      buf2=stop2;
2242
      buf1=start1+len2;
2243
      DBUG_ASSERT(buf1 < stop1);
2244
      for (carry=0; buf2 > start2; buf1--)
2245
      {
2246
        dec1 hi, lo;
2247
        x=guess * (*--buf2);
2248
        hi=(dec1)(x/DIG_BASE);
2249
        lo=(dec1)(x-((dec2)hi)*DIG_BASE);
2250
        SUB2(*buf1, *buf1, lo, carry);
2251
        carry+=hi;
2252
      }
2253
      carry= dcarry < carry;
2254
2255
      /* D5: check the remainder */
2256
      if (unlikely(carry))
2257
      {
2258
        /* D6: correct the guess */
2259
        guess--;
2260
        buf2=stop2;
2261
        buf1=start1+len2;
2262
        for (carry=0; buf2 > start2; buf1--)
2263
        {
2264
          ADD(*buf1, *buf1, *--buf2, carry);
2265
        }
2266
      }
2267
    }
2268
    if (likely(div_mod))
2269
      *buf0=(dec1)guess;
2270
    dcarry= *start1;
2271
    start1++;
2272
  }
2273
  if (mod)
2274
  {
2275
    /*
2276
      now the result is in tmp1, it has
2277
        intg=prec1-frac1
2278
        frac=max(frac1, frac2)=to->frac
2279
    */
2280
    if (dcarry)
2281
      *--start1=dcarry;
2282
    buf0=to->buf;
2283
    intg0=(int) (ROUND_UP(prec1-frac1)-(start1-tmp1));
2284
    frac0=ROUND_UP(to->frac);
2285
    error=E_DEC_OK;
2286
    if (unlikely(frac0==0 && intg0==0))
2287
    {
2288
      decimal_make_zero(to);
2289
      goto done;
2290
    }
2291
    if (intg0<=0)
2292
    {
2293
      if (unlikely(-intg0 >= to->len))
2294
      {
2295
        decimal_make_zero(to);
2296
        error=E_DEC_TRUNCATED;
2297
        goto done;
2298
      }
2299
      stop1=start1+frac0;
2300
      frac0+=intg0;
2301
      to->intg=0;
2302
      while (intg0++ < 0)
2303
        *buf0++=0;
2304
    }
2305
    else
2306
    {
2307
      if (unlikely(intg0 > to->len))
2308
      {
2309
        frac0=0;
2310
        intg0=to->len;
2311
        error=E_DEC_OVERFLOW;
2312
        goto done;
2313
      }
2314
      DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
2315
      stop1=start1+frac0+intg0;
2316
      to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
2317
    }
2318
    if (unlikely(intg0+frac0 > to->len))
2319
    {
2320
      stop1-=frac0+intg0-to->len;
2321
      frac0=to->len-intg0;
2322
      to->frac=frac0*DIG_PER_DEC1;
2323
        error=E_DEC_TRUNCATED;
2324
    }
2325
    DBUG_ASSERT(buf0 + (stop1 - start1) <= to->buf + to->len);
2326
    while (start1 < stop1)
2327
        *buf0++=*start1++;
2328
  }
2329
done:
2330
  my_afree(tmp1);
2331
  return error;
2332
}
2333
2334
/*
2335
  division of two decimals
2336
2337
  SYNOPSIS
2338
    decimal_div()
2339
      from1   - dividend
2340
      from2   - divisor
2341
      to      - quotient
2342
2343
  RETURN VALUE
2344
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2345
2346
  NOTES
2347
    see do_div_mod()
2348
*/
2349
2350
int
2351
decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to, int scale_incr)
2352
{
2353
  return do_div_mod(from1, from2, to, 0, scale_incr);
2354
}
2355
2356
/*
2357
  modulus
2358
2359
  SYNOPSIS
2360
    decimal_mod()
2361
      from1   - dividend
2362
      from2   - divisor
2363
      to      - modulus
2364
2365
  RETURN VALUE
2366
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2367
2368
  NOTES
2369
    see do_div_mod()
2370
2371
  DESCRIPTION
2372
    the modulus R in    R = M mod N
2373
2374
   is defined as
2375
2376
     0 <= |R| < |M|
2377
     sign R == sign M
2378
     R = M - k*N, where k is integer
2379
2380
   thus, there's no requirement for M or N to be integers
2381
*/
2382
2383
int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to)
2384
{
2385
  return do_div_mod(from1, from2, 0, to, 0);
2386
}
2387
2388
#ifdef MAIN
2389
2390
int full= 0;
2391
decimal_t a, b, c;
2392
char buf1[100], buf2[100], buf3[100];
2393
2394
void dump_decimal(decimal_t *d)
2395
{
2396
  int i;
2397
  printf("/* intg=%d, frac=%d, sign=%d, buf[]={", d->intg, d->frac, d->sign);
2398
  for (i=0; i < ROUND_UP(d->frac)+ROUND_UP(d->intg)-1; i++)
2399
    printf("%09d, ", d->buf[i]);
2400
  printf("%09d} */ ", d->buf[i]);
2401
}
2402
2403
2404
void check_result_code(int actual, int want)
2405
{
2406
  if (actual != want)
2407
  {
2408
    printf("\n^^^^^^^^^^^^^ must return %d\n", want);
2409
    exit(1);
2410
  }
2411
}
2412
2413
2414
void print_decimal(decimal_t *d, const char *orig, int actual, int want)
2415
{
2416
  char s[100];
2417
  int slen=sizeof(s);
2418
2419
  if (full) dump_decimal(d);
2420
  decimal2string(d, s, &slen, 0, 0, 0);
2421
  printf("'%s'", s);
2422
  check_result_code(actual, want);
2423
  if (orig && strcmp(orig, s))
2424
  {
2425
    printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2426
    exit(1);
2427
  }
2428
}
2429
2430
void test_d2s()
2431
{
2432
  char s[100];
2433
  int slen, res;
2434
2435
  /***********************************/
2436
  printf("==== decimal2string ====\n");
2437
  a.buf[0]=12345; a.intg=5; a.frac=0; a.sign=0;
2438
  slen=sizeof(s);
2439
  res=decimal2string(&a, s, &slen, 0, 0, 0);
2440
  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
2441
2442
  a.buf[1]=987000000; a.frac=3;
2443
  slen=sizeof(s);
2444
  res=decimal2string(&a, s, &slen, 0, 0, 0);
2445
  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
2446
2447
  a.sign=1;
2448
  slen=sizeof(s);
2449
  res=decimal2string(&a, s, &slen, 0, 0, 0);
2450
  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
2451
2452
  slen=8;
2453
  res=decimal2string(&a, s, &slen, 0, 0, 0);
2454
  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
2455
2456
  slen=5;
2457
  res=decimal2string(&a, s, &slen, 0, 0, 0);
2458
  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
2459
2460
  a.buf[0]=987000000; a.frac=3; a.intg=0;
2461
  slen=sizeof(s);
2462
  res=decimal2string(&a, s, &slen, 0, 0, 0);
2463
  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
2464
}
2465
2466
void test_s2d(const char *s, const char *orig, int ex)
2467
{
2468
  char s1[100], *end;
2469
  int res;
2470
  sprintf(s1, "'%s'", s);
2471
  end= strend(s);
2472
  printf("len=%2d %-30s => res=%d    ", a.len, s1,
2473
         (res= string2decimal(s, &a, &end)));
2474
  print_decimal(&a, orig, res, ex);
2475
  printf("\n");
2476
}
2477
2478
void test_d2f(const char *s, int ex)
2479
{
2480
  char s1[100], *end;
2481
  double x;
2482
  int res;
2483
2484
  sprintf(s1, "'%s'", s);
2485
  end= strend(s);
2486
  string2decimal(s, &a, &end);
2487
  res=decimal2double(&a, &x);
2488
  if (full) dump_decimal(&a);
2489
  printf("%-40s => res=%d    %.*g\n", s1, res, a.intg+a.frac, x);
2490
  check_result_code(res, ex);
2491
}
2492
2493
void test_d2b2d(const char *str, int p, int s, const char *orig, int ex)
2494
{
2495
  char s1[100], buf[100], *end;
2496
  int res, i, size=decimal_bin_size(p, s);
2497
2498
  sprintf(s1, "'%s'", str);
2499
  end= strend(str);
2500
  string2decimal(str, &a, &end);
2501
  res=decimal2bin(&a, buf, p, s);
2502
  printf("%-31s {%2d, %2d} => res=%d size=%-2d ", s1, p, s, res, size);
2503
  if (full)
2504
  {
2505
    printf("0x");
2506
    for (i=0; i < size; i++)
2507
      printf("%02x", ((uchar *)buf)[i]);
2508
  }
2509
  res=bin2decimal(buf, &a, p, s);
2510
  printf(" => res=%d ", res);
2511
  print_decimal(&a, orig, res, ex);
2512
  printf("\n");
2513
}
2514
2515
void test_f2d(double from, int ex)
2516
{
2517
  int res;
2518
2519
  res=double2decimal(from, &a);
2520
  printf("%-40.*f => res=%d    ", DBL_DIG-2, from, res);
2521
  print_decimal(&a, 0, res, ex);
2522
  printf("\n");
2523
}
2524
151 by Brian Aker
Ulonglong to uint64_t
2525
void test_ull2d(uint64_t from, const char *orig, int ex)
1 by brian
clean slate
2526
{
2527
  char s[100];
2528
  int res;
2529
151 by Brian Aker
Ulonglong to uint64_t
2530
  res=uint64_t2decimal(from, &a);
152 by Brian Aker
longlong replacement
2531
  int64_t10_to_str(from,s,10);
1 by brian
clean slate
2532
  printf("%-40s => res=%d    ", s, res);
2533
  print_decimal(&a, orig, res, ex);
2534
  printf("\n");
2535
}
2536
152 by Brian Aker
longlong replacement
2537
void test_ll2d(int64_t from, const char *orig, int ex)
1 by brian
clean slate
2538
{
2539
  char s[100];
2540
  int res;
2541
152 by Brian Aker
longlong replacement
2542
  res=int64_t2decimal(from, &a);
2543
  int64_t10_to_str(from,s,-10);
1 by brian
clean slate
2544
  printf("%-40s => res=%d    ", s, res);
2545
  print_decimal(&a, orig, res, ex);
2546
  printf("\n");
2547
}
2548
2549
void test_d2ull(const char *s, const char *orig, int ex)
2550
{
2551
  char s1[100], *end;
151 by Brian Aker
Ulonglong to uint64_t
2552
  uint64_t x;
1 by brian
clean slate
2553
  int res;
2554
2555
  end= strend(s);
2556
  string2decimal(s, &a, &end);
151 by Brian Aker
Ulonglong to uint64_t
2557
  res=decimal2uint64_t(&a, &x);
1 by brian
clean slate
2558
  if (full) dump_decimal(&a);
152 by Brian Aker
longlong replacement
2559
  int64_t10_to_str(x,s1,10);
1 by brian
clean slate
2560
  printf("%-40s => res=%d    %s\n", s, res, s1);
2561
  check_result_code(res, ex);
2562
  if (orig && strcmp(orig, s1))
2563
  {
2564
    printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2565
    exit(1);
2566
  }
2567
}
2568
2569
void test_d2ll(const char *s, const char *orig, int ex)
2570
{
2571
  char s1[100], *end;
152 by Brian Aker
longlong replacement
2572
  int64_t x;
1 by brian
clean slate
2573
  int res;
2574
2575
  end= strend(s);
2576
  string2decimal(s, &a, &end);
152 by Brian Aker
longlong replacement
2577
  res=decimal2int64_t(&a, &x);
1 by brian
clean slate
2578
  if (full) dump_decimal(&a);
152 by Brian Aker
longlong replacement
2579
  int64_t10_to_str(x,s1,-10);
1 by brian
clean slate
2580
  printf("%-40s => res=%d    %s\n", s, res, s1);
2581
  check_result_code(res, ex);
2582
  if (orig && strcmp(orig, s1))
2583
  {
2584
    printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2585
    exit(1);
2586
  }
2587
}
2588
2589
void test_da(const char *s1, const char *s2, const char *orig, int ex)
2590
{
2591
  char s[100], *end;
2592
  int res;
2593
  sprintf(s, "'%s' + '%s'", s1, s2);
2594
  end= strend(s1);
2595
  string2decimal(s1, &a, &end);
2596
  end= strend(s2);
2597
  string2decimal(s2, &b, &end);
2598
  res=decimal_add(&a, &b, &c);
2599
  printf("%-40s => res=%d    ", s, res);
2600
  print_decimal(&c, orig, res, ex);
2601
  printf("\n");
2602
}
2603
2604
void test_ds(const char *s1, const char *s2, const char *orig, int ex)
2605
{
2606
  char s[100], *end;
2607
  int res;
2608
  sprintf(s, "'%s' - '%s'", s1, s2);
2609
  end= strend(s1);
2610
  string2decimal(s1, &a, &end);
2611
  end= strend(s2);
2612
  string2decimal(s2, &b, &end);
2613
  res=decimal_sub(&a, &b, &c);
2614
  printf("%-40s => res=%d    ", s, res);
2615
  print_decimal(&c, orig, res, ex);
2616
  printf("\n");
2617
}
2618
2619
void test_dc(const char *s1, const char *s2, int orig)
2620
{
2621
  char s[100], *end;
2622
  int res;
2623
  sprintf(s, "'%s' <=> '%s'", s1, s2);
2624
  end= strend(s1);
2625
  string2decimal(s1, &a, &end);
2626
  end= strend(s2);
2627
  string2decimal(s2, &b, &end);
2628
  res=decimal_cmp(&a, &b);
2629
  printf("%-40s => res=%d\n", s, res);
2630
  if (orig != res)
2631
  {
2632
    printf("\n^^^^^^^^^^^^^ must've been %d\n", orig);
2633
    exit(1);
2634
  }
2635
}
2636
2637
void test_dm(const char *s1, const char *s2, const char *orig, int ex)
2638
{
2639
  char s[100], *end;
2640
  int res;
2641
  sprintf(s, "'%s' * '%s'", s1, s2);
2642
  end= strend(s1);
2643
  string2decimal(s1, &a, &end);
2644
  end= strend(s2);
2645
  string2decimal(s2, &b, &end);
2646
  res=decimal_mul(&a, &b, &c);
2647
  printf("%-40s => res=%d    ", s, res);
2648
  print_decimal(&c, orig, res, ex);
2649
  printf("\n");
2650
}
2651
2652
void test_dv(const char *s1, const char *s2, const char *orig, int ex)
2653
{
2654
  char s[100], *end;
2655
  int res;
2656
  sprintf(s, "'%s' / '%s'", s1, s2);
2657
  end= strend(s1);
2658
  string2decimal(s1, &a, &end);
2659
  end= strend(s2);
2660
  string2decimal(s2, &b, &end);
2661
  res=decimal_div(&a, &b, &c, 5);
2662
  printf("%-40s => res=%d    ", s, res);
2663
  check_result_code(res, ex);
2664
  if (res == E_DEC_DIV_ZERO)
2665
    printf("E_DEC_DIV_ZERO");
2666
  else
2667
    print_decimal(&c, orig, res, ex);
2668
  printf("\n");
2669
}
2670
2671
void test_md(const char *s1, const char *s2, const char *orig, int ex)
2672
{
2673
  char s[100], *end;
2674
  int res;
2675
  sprintf(s, "'%s' %% '%s'", s1, s2);
2676
  end= strend(s1);
2677
  string2decimal(s1, &a, &end);
2678
  end= strend(s2);
2679
  string2decimal(s2, &b, &end);
2680
  res=decimal_mod(&a, &b, &c);
2681
  printf("%-40s => res=%d    ", s, res);
2682
  check_result_code(res, ex);
2683
  if (res == E_DEC_DIV_ZERO)
2684
    printf("E_DEC_DIV_ZERO");
2685
  else
2686
    print_decimal(&c, orig, res, ex);
2687
  printf("\n");
2688
}
2689
2690
const char *round_mode[]=
2691
{"TRUNCATE", "HALF_EVEN", "HALF_UP", "CEILING", "FLOOR"};
2692
2693
void test_ro(const char *s1, int n, decimal_round_mode mode, const char *orig,
2694
             int ex)
2695
{
2696
  char s[100], *end;
2697
  int res;
2698
  sprintf(s, "'%s', %d, %s", s1, n, round_mode[mode]);
2699
  end= strend(s1);
2700
  string2decimal(s1, &a, &end);
2701
  res=decimal_round(&a, &b, n, mode);
2702
  printf("%-40s => res=%d    ", s, res);
2703
  print_decimal(&b, orig, res, ex);
2704
  printf("\n");
2705
}
2706
2707
2708
void test_mx(int precision, int frac, const char *orig)
2709
{
2710
  char s[100];
2711
  sprintf(s, "%d, %d", precision, frac);
2712
  max_decimal(precision, frac, &a);
2713
  printf("%-40s =>          ", s);
2714
  print_decimal(&a, orig, 0, 0);
2715
  printf("\n");
2716
}
2717
2718
2719
void test_pr(const char *s1, int prec, int dec, char filler, const char *orig,
2720
             int ex)
2721
{
2722
  char s[100], *end;
2723
  char s2[100];
2724
  int slen= sizeof(s2);
2725
  int res;
2726
2727
  sprintf(s, filler ? "'%s', %d, %d, '%c'" : "'%s', %d, %d, '\\0'",
2728
          s1, prec, dec, filler);
2729
  end= strend(s1);
2730
  string2decimal(s1, &a, &end);
2731
  res= decimal2string(&a, s2, &slen, prec, dec, filler);
2732
  printf("%-40s => res=%d    '%s'", s, res, s2);
2733
  check_result_code(res, ex);
2734
  if (orig && strcmp(orig, s2))
2735
  {
2736
    printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2737
    exit(1);
2738
  }
2739
  printf("\n");
2740
}
2741
2742
2743
void test_sh(const char *s1, int shift, const char *orig, int ex)
2744
{
2745
  char s[100], *end;
2746
  int res;
2747
  sprintf(s, "'%s' %s %d", s1, ((shift < 0) ? ">>" : "<<"), abs(shift));
2748
  end= strend(s1);
2749
  string2decimal(s1, &a, &end);
2750
  res= decimal_shift(&a, shift);
2751
  printf("%-40s => res=%d    ", s, res);
2752
  print_decimal(&a, orig, res, ex);
2753
  printf("\n");
2754
}
2755
2756
2757
void test_fr(const char *s1, const char *orig)
2758
{
2759
  char s[100], *end;
2760
  sprintf(s, "'%s'", s1);
2761
  printf("%-40s =>          ", s);
2762
  end= strend(s1);
2763
  string2decimal(s1, &a, &end);
2764
  a.frac= decimal_actual_fraction(&a);
2765
  print_decimal(&a, orig, 0, 0);
2766
  printf("\n");
2767
}
2768
2769
2770
int main()
2771
{
2772
  a.buf=(void*)buf1;
2773
  a.len=sizeof(buf1)/sizeof(dec1);
2774
  b.buf=(void*)buf2;
2775
  b.len=sizeof(buf2)/sizeof(dec1);
2776
  c.buf=(void*)buf3;
2777
  c.len=sizeof(buf3)/sizeof(dec1);
2778
2779
  if (full)
2780
    test_d2s();
2781
2782
  printf("==== string2decimal ====\n");
2783
  test_s2d("12345", "12345", 0);
2784
  test_s2d("12345.", "12345", 0);
2785
  test_s2d("123.45", "123.45", 0);
2786
  test_s2d("-123.45", "-123.45", 0);
2787
  test_s2d(".00012345000098765", "0.00012345000098765", 0);
2788
  test_s2d(".12345000098765", "0.12345000098765", 0);
2789
  test_s2d("-.000000012345000098765", "-0.000000012345000098765", 0);
2790
  test_s2d("1234500009876.5", "1234500009876.5", 0);
2791
  a.len=1;
2792
  test_s2d("123450000098765", "98765", 2);
2793
  test_s2d("123450.000098765", "123450", 1);
2794
  a.len=sizeof(buf1)/sizeof(dec1);
2795
  test_s2d("123E5", "12300000", 0);
2796
  test_s2d("123E-2", "1.23", 0);
2797
2798
  printf("==== decimal2double ====\n");
2799
  test_d2f("12345", 0);
2800
  test_d2f("123.45", 0);
2801
  test_d2f("-123.45", 0);
2802
  test_d2f("0.00012345000098765", 0);
2803
  test_d2f("1234500009876.5", 0);
2804
2805
  printf("==== double2decimal ====\n");
2806
  test_f2d(12345, 0);
2807
  test_f2d(1.0/3, 0);
2808
  test_f2d(-123.45, 0);
2809
  test_f2d(0.00012345000098765, 0);
2810
  test_f2d(1234500009876.5, 0);
2811
151 by Brian Aker
Ulonglong to uint64_t
2812
  printf("==== uint64_t2decimal ====\n");
80.1.1 by Brian Aker
LL() cleanup
2813
  test_ull2d(12345ULL, "12345", 0);
2814
  test_ull2d(0ULL, "0", 0);
2815
  test_ull2d(18446744073709551615ULL, "18446744073709551615", 0);
1 by brian
clean slate
2816
151 by Brian Aker
Ulonglong to uint64_t
2817
  printf("==== decimal2uint64_t ====\n");
1 by brian
clean slate
2818
  test_d2ull("12345", "12345", 0);
2819
  test_d2ull("0", "0", 0);
2820
  test_d2ull("18446744073709551615", "18446744073709551615", 0);
2821
  test_d2ull("18446744073709551616", "18446744073", 2);
2822
  test_d2ull("-1", "0", 2);
2823
  test_d2ull("1.23", "1", 1);
2824
  test_d2ull("9999999999999999999999999.000", "9999999999999999", 2);
2825
152 by Brian Aker
longlong replacement
2826
  printf("==== int64_t2decimal ====\n");
80.1.1 by Brian Aker
LL() cleanup
2827
  test_ll2d(12345LL, "-12345", 0);
2828
  test_ll2d(1LL, "-1", 0);
2829
  test_ll2d(9223372036854775807LL, "-9223372036854775807", 0);
2830
  test_ll2d(9223372036854775808ULL, "-9223372036854775808", 0);
1 by brian
clean slate
2831
152 by Brian Aker
longlong replacement
2832
  printf("==== decimal2int64_t ====\n");
1 by brian
clean slate
2833
  test_d2ll("18446744073709551615", "18446744073", 2);
2834
  test_d2ll("-1", "-1", 0);
2835
  test_d2ll("-1.23", "-1", 1);
2836
  test_d2ll("-9223372036854775807", "-9223372036854775807", 0);
2837
  test_d2ll("-9223372036854775808", "-9223372036854775808", 0);
2838
  test_d2ll("9223372036854775808", "9223372036854775807", 2);
2839
2840
  printf("==== do_add ====\n");
2841
  test_da(".00012345000098765" ,"123.45", "123.45012345000098765", 0);
2842
  test_da(".1" ,".45", "0.55", 0);
2843
  test_da("1234500009876.5" ,".00012345000098765", "1234500009876.50012345000098765", 0);
2844
  test_da("9999909999999.5" ,".555", "9999910000000.055", 0);
2845
  test_da("99999999" ,"1", "100000000", 0);
2846
  test_da("989999999" ,"1", "990000000", 0);
2847
  test_da("999999999" ,"1", "1000000000", 0);
2848
  test_da("12345" ,"123.45", "12468.45", 0);
2849
  test_da("-12345" ,"-123.45", "-12468.45", 0);
2850
  test_ds("-12345" ,"123.45", "-12468.45", 0);
2851
  test_ds("12345" ,"-123.45", "12468.45", 0);
2852
2853
  printf("==== do_sub ====\n");
2854
  test_ds(".00012345000098765", "123.45","-123.44987654999901235", 0);
2855
  test_ds("1234500009876.5", ".00012345000098765","1234500009876.49987654999901235", 0);
2856
  test_ds("9999900000000.5", ".555","9999899999999.945", 0);
2857
  test_ds("1111.5551", "1111.555","0.0001", 0);
2858
  test_ds(".555", ".555","0", 0);
2859
  test_ds("10000000", "1","9999999", 0);
2860
  test_ds("1000001000", ".1","1000000999.9", 0);
2861
  test_ds("1000000000", ".1","999999999.9", 0);
2862
  test_ds("12345", "123.45","12221.55", 0);
2863
  test_ds("-12345", "-123.45","-12221.55", 0);
2864
  test_da("-12345", "123.45","-12221.55", 0);
2865
  test_da("12345", "-123.45","12221.55", 0);
2866
  test_ds("123.45", "12345","-12221.55", 0);
2867
  test_ds("-123.45", "-12345","12221.55", 0);
2868
  test_da("123.45", "-12345","-12221.55", 0);
2869
  test_da("-123.45", "12345","12221.55", 0);
2870
  test_da("5", "-6.0","-1.0", 0);
2871
2872
  printf("==== decimal_mul ====\n");
2873
  test_dm("12", "10","120", 0);
2874
  test_dm("-123.456", "98765.4321","-12193185.1853376", 0);
2875
  test_dm("-123456000000", "98765432100000","-12193185185337600000000000", 0);
2876
  test_dm("123456", "987654321","121931851853376", 0);
2877
  test_dm("123456", "9876543210","1219318518533760", 0);
2878
  test_dm("123", "0.01","1.23", 0);
2879
  test_dm("123", "0","0", 0);
2880
2881
  printf("==== decimal_div ====\n");
2882
  test_dv("120", "10","12.000000000", 0);
2883
  test_dv("123", "0.01","12300.000000000", 0);
2884
  test_dv("120", "100000000000.00000","0.000000001200000000", 0);
2885
  test_dv("123", "0","", 4);
2886
  test_dv("0", "0", "", 4);
2887
  test_dv("-12193185.1853376", "98765.4321","-123.456000000000000000", 0);
2888
  test_dv("121931851853376", "987654321","123456.000000000", 0);
2889
  test_dv("0", "987","0", 0);
2890
  test_dv("1", "3","0.333333333", 0);
2891
  test_dv("1.000000000000", "3","0.333333333333333333", 0);
2892
  test_dv("1", "1","1.000000000", 0);
2893
  test_dv("0.0123456789012345678912345", "9999999999","0.000000000001234567890246913578148141", 0);
2894
  test_dv("10.333000000", "12.34500","0.837019036046982584042122316", 0);
2895
  test_dv("10.000000000060", "2","5.000000000030000000", 0);
2896
2897
  printf("==== decimal_mod ====\n");
2898
  test_md("234","10","4", 0);
2899
  test_md("234.567","10.555","2.357", 0);
2900
  test_md("-234.567","10.555","-2.357", 0);
2901
  test_md("234.567","-10.555","2.357", 0);
2902
  c.buf[1]=0x3ABECA;
2903
  test_md("99999999999999999999999999999999999999","3","0", 0);
2904
  if (c.buf[1] != 0x3ABECA)
2905
  {
2906
    printf("%X - overflow\n", c.buf[1]);
2907
    exit(1);
2908
  }
2909
2910
  printf("==== decimal2bin/bin2decimal ====\n");
2911
  test_d2b2d("-10.55", 4, 2,"-10.55", 0);
2912
  test_d2b2d("0.0123456789012345678912345", 30, 25,"0.0123456789012345678912345", 0);
2913
  test_d2b2d("12345", 5, 0,"12345", 0);
2914
  test_d2b2d("12345", 10, 3,"12345.000", 0);
2915
  test_d2b2d("123.45", 10, 3,"123.450", 0);
2916
  test_d2b2d("-123.45", 20, 10,"-123.4500000000", 0);
2917
  test_d2b2d(".00012345000098765", 15, 14,"0.00012345000098", 0);
2918
  test_d2b2d(".00012345000098765", 22, 20,"0.00012345000098765000", 0);
2919
  test_d2b2d(".12345000098765", 30, 20,"0.12345000098765000000", 0);
2920
  test_d2b2d("-.000000012345000098765", 30, 20,"-0.00000001234500009876", 0);
2921
  test_d2b2d("1234500009876.5", 30, 5,"1234500009876.50000", 0);
2922
  test_d2b2d("111111111.11", 10, 2,"11111111.11", 0);
2923
  test_d2b2d("000000000.01", 7, 3,"0.010", 0);
2924
  test_d2b2d("123.4", 10, 2, "123.40", 0);
2925
2926
2927
  printf("==== decimal_cmp ====\n");
2928
  test_dc("12","13",-1);
2929
  test_dc("13","12",1);
2930
  test_dc("-10","10",-1);
2931
  test_dc("10","-10",1);
2932
  test_dc("-12","-13",1);
2933
  test_dc("0","12",-1);
2934
  test_dc("-10","0",-1);
2935
  test_dc("4","4",0);
2936
2937
  printf("==== decimal_round ====\n");
2938
  test_ro("5678.123451",-4,TRUNCATE,"0", 0);
2939
  test_ro("5678.123451",-3,TRUNCATE,"5000", 0);
2940
  test_ro("5678.123451",-2,TRUNCATE,"5600", 0);
2941
  test_ro("5678.123451",-1,TRUNCATE,"5670", 0);
2942
  test_ro("5678.123451",0,TRUNCATE,"5678", 0);
2943
  test_ro("5678.123451",1,TRUNCATE,"5678.1", 0);
2944
  test_ro("5678.123451",2,TRUNCATE,"5678.12", 0);
2945
  test_ro("5678.123451",3,TRUNCATE,"5678.123", 0);
2946
  test_ro("5678.123451",4,TRUNCATE,"5678.1234", 0);
2947
  test_ro("5678.123451",5,TRUNCATE,"5678.12345", 0);
2948
  test_ro("5678.123451",6,TRUNCATE,"5678.123451", 0);
2949
  test_ro("-5678.123451",-4,TRUNCATE,"0", 0);
2950
  memset(buf2, 33, sizeof(buf2));
2951
  test_ro("99999999999999999999999999999999999999",-31,TRUNCATE,"99999990000000000000000000000000000000", 0);
2952
  test_ro("15.1",0,HALF_UP,"15", 0);
2953
  test_ro("15.5",0,HALF_UP,"16", 0);
2954
  test_ro("15.9",0,HALF_UP,"16", 0);
2955
  test_ro("-15.1",0,HALF_UP,"-15", 0);
2956
  test_ro("-15.5",0,HALF_UP,"-16", 0);
2957
  test_ro("-15.9",0,HALF_UP,"-16", 0);
2958
  test_ro("15.1",1,HALF_UP,"15.1", 0);
2959
  test_ro("-15.1",1,HALF_UP,"-15.1", 0);
2960
  test_ro("15.17",1,HALF_UP,"15.2", 0);
2961
  test_ro("15.4",-1,HALF_UP,"20", 0);
2962
  test_ro("-15.4",-1,HALF_UP,"-20", 0);
2963
  test_ro("5.4",-1,HALF_UP,"10", 0);
2964
  test_ro(".999", 0, HALF_UP, "1", 0);
2965
  memset(buf2, 33, sizeof(buf2));
2966
  test_ro("999999999", -9, HALF_UP, "1000000000", 0);
2967
  test_ro("15.1",0,HALF_EVEN,"15", 0);
2968
  test_ro("15.5",0,HALF_EVEN,"16", 0);
2969
  test_ro("14.5",0,HALF_EVEN,"14", 0);
2970
  test_ro("15.9",0,HALF_EVEN,"16", 0);
2971
  test_ro("15.1",0,CEILING,"16", 0);
2972
  test_ro("-15.1",0,CEILING,"-15", 0);
2973
  test_ro("15.1",0,FLOOR,"15", 0);
2974
  test_ro("-15.1",0,FLOOR,"-16", 0);
2975
  test_ro("999999999999999999999.999", 0, CEILING,"1000000000000000000000", 0);
2976
  test_ro("-999999999999999999999.999", 0, FLOOR,"-1000000000000000000000", 0);
2977
2978
  b.buf[0]=DIG_BASE+1;
2979
  b.buf++;
2980
  test_ro(".3", 0, HALF_UP, "0", 0);
2981
  b.buf--;
2982
  if (b.buf[0] != DIG_BASE+1)
2983
  {
2984
    printf("%d - underflow\n", b.buf[0]);
2985
    exit(1);
2986
  }
2987
2988
  printf("==== max_decimal ====\n");
2989
  test_mx(1,1,"0.9");
2990
  test_mx(1,0,"9");
2991
  test_mx(2,1,"9.9");
2992
  test_mx(4,2,"99.99");
2993
  test_mx(6,3,"999.999");
2994
  test_mx(8,4,"9999.9999");
2995
  test_mx(10,5,"99999.99999");
2996
  test_mx(12,6,"999999.999999");
2997
  test_mx(14,7,"9999999.9999999");
2998
  test_mx(16,8,"99999999.99999999");
2999
  test_mx(18,9,"999999999.999999999");
3000
  test_mx(20,10,"9999999999.9999999999");
3001
  test_mx(20,20,"0.99999999999999999999");
3002
  test_mx(20,0,"99999999999999999999");
3003
  test_mx(40,20,"99999999999999999999.99999999999999999999");
3004
3005
  printf("==== decimal2string ====\n");
3006
  test_pr("123.123", 0, 0, 0, "123.123", 0);
3007
  test_pr("123.123", 7, 3, '0', "123.123", 0);
3008
  test_pr("123.123", 9, 3, '0', "00123.123", 0);
3009
  test_pr("123.123", 9, 4, '0', "0123.1230", 0);
3010
  test_pr("123.123", 9, 5, '0', "123.12300", 0);
3011
  test_pr("123.123", 9, 2, '0', "000123.12", 1);
3012
  test_pr("123.123", 9, 6, '0', "23.123000", 2);
3013
3014
  printf("==== decimal_shift ====\n");
3015
  test_sh("123.123", 1, "1231.23", 0);
3016
  test_sh("123457189.123123456789000", 1, "1234571891.23123456789", 0);
3017
  test_sh("123457189.123123456789000", 4, "1234571891231.23456789", 0);
3018
  test_sh("123457189.123123456789000", 8, "12345718912312345.6789", 0);
3019
  test_sh("123457189.123123456789000", 9, "123457189123123456.789", 0);
3020
  test_sh("123457189.123123456789000", 10, "1234571891231234567.89", 0);
3021
  test_sh("123457189.123123456789000", 17, "12345718912312345678900000", 0);
3022
  test_sh("123457189.123123456789000", 18, "123457189123123456789000000", 0);
3023
  test_sh("123457189.123123456789000", 19, "1234571891231234567890000000", 0);
3024
  test_sh("123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
3025
  test_sh("123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
3026
  test_sh("123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
3027
  test_sh("000000000000000000000000123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
3028
  test_sh("00000000123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
3029
  test_sh("00000000000000000123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
3030
  test_sh("123", 1, "1230", 0);
3031
  test_sh("123", 10, "1230000000000", 0);
3032
  test_sh(".123", 1, "1.23", 0);
3033
  test_sh(".123", 10, "1230000000", 0);
3034
  test_sh(".123", 14, "12300000000000", 0);
3035
  test_sh("000.000", 1000, "0", 0);
3036
  test_sh("000.", 1000, "0", 0);
3037
  test_sh(".000", 1000, "0", 0);
3038
  test_sh("1", 1000, "1", 2);
3039
  test_sh("123.123", -1, "12.3123", 0);
3040
  test_sh("123987654321.123456789000", -1, "12398765432.1123456789", 0);
3041
  test_sh("123987654321.123456789000", -2, "1239876543.21123456789", 0);
3042
  test_sh("123987654321.123456789000", -3, "123987654.321123456789", 0);
3043
  test_sh("123987654321.123456789000", -8, "1239.87654321123456789", 0);
3044
  test_sh("123987654321.123456789000", -9, "123.987654321123456789", 0);
3045
  test_sh("123987654321.123456789000", -10, "12.3987654321123456789", 0);
3046
  test_sh("123987654321.123456789000", -11, "1.23987654321123456789", 0);
3047
  test_sh("123987654321.123456789000", -12, "0.123987654321123456789", 0);
3048
  test_sh("123987654321.123456789000", -13, "0.0123987654321123456789", 0);
3049
  test_sh("123987654321.123456789000", -14, "0.00123987654321123456789", 0);
3050
  test_sh("00000087654321.123456789000", -14, "0.00000087654321123456789", 0);
3051
  a.len= 2;
3052
  test_sh("123.123", -2, "1.23123", 0);
3053
  test_sh("123.123", -3, "0.123123", 0);
3054
  test_sh("123.123", -6, "0.000123123", 0);
3055
  test_sh("123.123", -7, "0.0000123123", 0);
3056
  test_sh("123.123", -15, "0.000000000000123123", 0);
3057
  test_sh("123.123", -16, "0.000000000000012312", 1);
3058
  test_sh("123.123", -17, "0.000000000000001231", 1);
3059
  test_sh("123.123", -18, "0.000000000000000123", 1);
3060
  test_sh("123.123", -19, "0.000000000000000012", 1);
3061
  test_sh("123.123", -20, "0.000000000000000001", 1);
3062
  test_sh("123.123", -21, "0", 1);
3063
  test_sh(".000000000123", -1, "0.0000000000123", 0);
3064
  test_sh(".000000000123", -6, "0.000000000000000123", 0);
3065
  test_sh(".000000000123", -7, "0.000000000000000012", 1);
3066
  test_sh(".000000000123", -8, "0.000000000000000001", 1);
3067
  test_sh(".000000000123", -9, "0", 1);
3068
  test_sh(".000000000123", 1, "0.00000000123", 0);
3069
  test_sh(".000000000123", 8, "0.0123", 0);
3070
  test_sh(".000000000123", 9, "0.123", 0);
3071
  test_sh(".000000000123", 10, "1.23", 0);
3072
  test_sh(".000000000123", 17, "12300000", 0);
3073
  test_sh(".000000000123", 18, "123000000", 0);
3074
  test_sh(".000000000123", 19, "1230000000", 0);
3075
  test_sh(".000000000123", 20, "12300000000", 0);
3076
  test_sh(".000000000123", 21, "123000000000", 0);
3077
  test_sh(".000000000123", 22, "1230000000000", 0);
3078
  test_sh(".000000000123", 23, "12300000000000", 0);
3079
  test_sh(".000000000123", 24, "123000000000000", 0);
3080
  test_sh(".000000000123", 25, "1230000000000000", 0);
3081
  test_sh(".000000000123", 26, "12300000000000000", 0);
3082
  test_sh(".000000000123", 27, "123000000000000000", 0);
3083
  test_sh(".000000000123", 28, "0.000000000123", 2);
3084
  test_sh("123456789.987654321", -1, "12345678.998765432", 1);
3085
  test_sh("123456789.987654321", -2, "1234567.899876543", 1);
3086
  test_sh("123456789.987654321", -8, "1.234567900", 1);
3087
  test_sh("123456789.987654321", -9, "0.123456789987654321", 0);
3088
  test_sh("123456789.987654321", -10, "0.012345678998765432", 1);
3089
  test_sh("123456789.987654321", -17, "0.000000001234567900", 1);
3090
  test_sh("123456789.987654321", -18, "0.000000000123456790", 1);
3091
  test_sh("123456789.987654321", -19, "0.000000000012345679", 1);
3092
  test_sh("123456789.987654321", -26, "0.000000000000000001", 1);
3093
  test_sh("123456789.987654321", -27, "0", 1);
3094
  test_sh("123456789.987654321", 1, "1234567900", 1);
3095
  test_sh("123456789.987654321", 2, "12345678999", 1);
3096
  test_sh("123456789.987654321", 4, "1234567899877", 1);
3097
  test_sh("123456789.987654321", 8, "12345678998765432", 1);
3098
  test_sh("123456789.987654321", 9, "123456789987654321", 0);
3099
  test_sh("123456789.987654321", 10, "123456789.987654321", 2);
3100
  test_sh("123456789.987654321", 0, "123456789.987654321", 0);
3101
  a.len= sizeof(buf1)/sizeof(dec1);
3102
3103
  printf("==== decimal_actual_fraction ====\n");
3104
  test_fr("1.123456789000000000", "1.123456789");
3105
  test_fr("1.12345678000000000", "1.12345678");
3106
  test_fr("1.1234567000000000", "1.1234567");
3107
  test_fr("1.123456000000000", "1.123456");
3108
  test_fr("1.12345000000000", "1.12345");
3109
  test_fr("1.1234000000000", "1.1234");
3110
  test_fr("1.123000000000", "1.123");
3111
  test_fr("1.12000000000", "1.12");
3112
  test_fr("1.1000000000", "1.1");
3113
  test_fr("1.000000000", "1");
3114
  test_fr("1.0", "1");
3115
  test_fr("10000000000000000000.0", "10000000000000000000");
3116
3117
  return 0;
3118
}
3119
#endif