~drizzle-trunk/drizzle/development

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