~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to strings/decimal.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

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