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