~drizzle-trunk/drizzle/development

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