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