~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/decimal.cc

  • Committer: Stewart Smith
  • Date: 2010-03-18 12:01:34 UTC
  • mto: (1666.2.3 build)
  • mto: This revision was merged to the branch mainline in revision 1596.
  • Revision ID: stewart@flamingspork.com-20100318120134-45fdnsw8g3j6c7oy
move RAND() into a plugin

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
 
 
16
 
/** @file
17
 
 *
18
 
 * @brief  SQL standard-compliant decimal number handling
19
 
 *
20
 
 * @note
21
 
 * This library implements SQL standard "exact numeric" type
22
 
 * and is not at all generic, but rather intentinally crippled to
23
 
 * follow the standard :) 
24
 
 */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
25
15
 
26
16
/*
27
17
=======================================================================
 
18
  NOTE: this library implements SQL standard "exact numeric" type
 
19
  and is not at all generic, but rather intentinally crippled to
 
20
  follow the standard :)
 
21
=======================================================================
28
22
  Quoting the standard
29
23
  (SQL:2003, Part 2 Foundations, aka ISO/IEC 9075-2:2003)
30
24
 
118
112
#endif
119
113
 
120
114
#include <algorithm>
121
 
#include <time.h>
122
 
#include "drizzled/current_session.h"
123
 
#include "drizzled/error.h"
124
 
#include "drizzled/field.h"
125
 
#include "drizzled/internal/my_sys.h"
126
115
 
127
116
using namespace std;
128
117
 
129
118
namespace drizzled
130
119
{
131
 
/**
132
 
  report result of decimal operation.
133
 
 
134
 
  @param result  decimal library return code (E_DEC_* see include/decimal.h)
135
 
 
136
 
  @todo
137
 
    Fix error messages
138
 
 
139
 
  @return
140
 
    result
141
 
*/
142
 
 
143
 
int decimal_operation_results(int result)
144
 
{
145
 
  switch (result) {
146
 
  case E_DEC_OK:
147
 
    break;
148
 
  case E_DEC_TRUNCATED:
149
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
150
 
                        ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
151
 
                        "", (long)-1);
152
 
    break;
153
 
  case E_DEC_OVERFLOW:
154
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
155
 
                        ER_TRUNCATED_WRONG_VALUE,
156
 
                        ER(ER_TRUNCATED_WRONG_VALUE),
157
 
                        "DECIMAL", "");
158
 
    break;
159
 
  case E_DEC_DIV_ZERO:
160
 
    my_error(ER_DIVISION_BY_ZERO, MYF(0));
161
 
    break;
162
 
  case E_DEC_BAD_NUM:
163
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
164
 
                        ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
165
 
                        ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
166
 
                        "decimal", "", "", (long)-1);
167
 
    break;
168
 
  case E_DEC_OOM:
169
 
    my_error(ER_OUT_OF_RESOURCES, MYF(0));
170
 
    break;
171
 
  default:
172
 
    assert(0);
173
 
  }
174
 
  return result;
175
 
}
176
 
 
177
 
 
178
 
/**
179
 
  @brief Converting decimal to string
180
 
 
181
 
  @details Convert given my_decimal to String; allocate buffer as needed.
182
 
 
183
 
  @param[in]   mask        what problems to warn on (mask of E_DEC_* values)
184
 
  @param[in]   d           the decimal to print
185
 
  @param[in]   fixed_prec  overall number of digits if ZEROFILL, 0 otherwise
186
 
  @param[in]   fixed_dec   number of decimal places (if fixed_prec != 0)
187
 
  @param[in]   filler      what char to pad with (ZEROFILL et al.)
188
 
  @param[out]  *str        where to store the resulting string
189
 
 
190
 
  @return error code
191
 
    @retval E_DEC_OK
192
 
    @retval E_DEC_TRUNCATED
193
 
    @retval E_DEC_OVERFLOW
194
 
    @retval E_DEC_OOM
195
 
*/
196
 
 
197
 
int my_decimal2string(uint32_t mask, const my_decimal *d,
198
 
                      uint32_t fixed_prec, uint32_t fixed_dec,
199
 
                      char filler, String *str)
200
 
{
201
 
  /*
202
 
    Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a
203
 
    holds true iff the type is also ZEROFILL, which in turn implies
204
 
    UNSIGNED. Hence the buffer for a ZEROFILLed value is the length
205
 
    the user requested, plus one for a possible decimal point, plus
206
 
    one if the user only wanted decimal places, but we force a leading
207
 
    zero on them. Because the type is implicitly UNSIGNED, we do not
208
 
    need to reserve a character for the sign. For all other cases,
209
 
    fixed_prec will be 0, and my_decimal_string_length() will be called
210
 
    instead to calculate the required size of the buffer.
211
 
  */
212
 
  int length= (int)(fixed_prec
213
 
                    ? (uint32_t)(fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
214
 
                    : (uint32_t)my_decimal_string_length(d));
215
 
  int result;
216
 
  if (str->alloc(length))
217
 
    return check_result(mask, E_DEC_OOM);
218
 
  result= decimal2string((decimal_t*) d, (char*) str->ptr(),
219
 
                         &length, (int)fixed_prec, fixed_dec,
220
 
                         filler);
221
 
  str->length(length);
222
 
  return check_result(mask, result);
223
 
}
224
 
 
225
 
 
226
 
/**
227
 
  @brief  Convert from decimal to binary representation
228
 
 
229
 
  @param[in]   mask        error processing mask
230
 
  @param[in]   d           number for conversion
231
 
  @param[out]  bin         pointer to buffer where to write result
232
 
  @param[in]   prec        overall number of decimal digits
233
 
  @param[in]   scale       number of decimal digits after decimal point
234
 
 
235
 
  @note
236
 
    Before conversion we round number if it need but produce truncation
237
 
    error in this case
238
 
 
239
 
  @return error code
240
 
   @retval E_DEC_OK
241
 
   @retval E_DEC_TRUNCATED
242
 
   @retval E_DEC_OVERFLOW
243
 
*/
244
 
 
245
 
int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
246
 
                      int scale)
247
 
{
248
 
  int err1= E_DEC_OK, err2;
249
 
  my_decimal rounded;
250
 
  my_decimal2decimal(d, &rounded);
251
 
  rounded.frac= decimal_actual_fraction(&rounded);
252
 
  if (scale < rounded.frac)
253
 
  {
254
 
    err1= E_DEC_TRUNCATED;
255
 
    /* decimal_round can return only E_DEC_TRUNCATED */
256
 
    decimal_round(&rounded, &rounded, scale, HALF_UP);
257
 
  }
258
 
  err2= decimal2bin(&rounded, bin, prec, scale);
259
 
  if (!err2)
260
 
    err2= err1;
261
 
  return check_result(mask, err2);
262
 
}
263
 
 
264
 
 
265
 
/**
266
 
  @brief Convert string for decimal when string can be in some multibyte charset
267
 
 
268
 
  @param  mask            error processing mask
269
 
  @param  from            string to process
270
 
  @param  length          length of given string
271
 
  @param  charset         charset of given string
272
 
  @param  decimal_value   buffer for result storing
273
 
 
274
 
  @return Error code
275
 
   @retval E_DEC_OK
276
 
   @retval E_DEC_TRUNCATED
277
 
   @retval E_DEC_OVERFLOW
278
 
   @retval E_DEC_BAD_NUM
279
 
   @retval E_DEC_OOM
280
 
*/
281
 
 
282
 
int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
283
 
                   const CHARSET_INFO * charset, my_decimal *decimal_value)
284
 
{
285
 
  char *end, *from_end;
286
 
  int err;
287
 
  char buff[STRING_BUFFER_USUAL_SIZE];
288
 
  String tmp(buff, sizeof(buff), &my_charset_bin);
289
 
  if (charset->mbminlen > 1)
290
 
  {
291
 
    size_t dummy_errors;
292
 
    tmp.copy(from, length, charset, &my_charset_utf8_general_ci, &dummy_errors);
293
 
    from= tmp.ptr();
294
 
    length=  tmp.length();
295
 
    charset= &my_charset_bin;
296
 
  }
297
 
  from_end= end= (char*) from+length;
298
 
  err= string2decimal((char *)from, (decimal_t*) decimal_value, &end);
299
 
  if (end != from_end && !err)
300
 
  {
301
 
    /* Give warning if there is something other than end space */
302
 
    for ( ; end < from_end; end++)
303
 
    {
304
 
      if (!my_isspace(&my_charset_utf8_general_ci, *end))
305
 
      {
306
 
        err= E_DEC_TRUNCATED;
307
 
        break;
308
 
      }
309
 
    }
310
 
  }
311
 
  check_result_and_overflow(mask, err, decimal_value);
312
 
  return err;
313
 
}
314
 
 
315
 
 
316
 
my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec)
317
 
{
318
 
  int64_t date;
319
 
  date = (ltime->year*100L + ltime->month)*100L + ltime->day;
320
 
  if (ltime->time_type > DRIZZLE_TIMESTAMP_DATE)
321
 
    date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
322
 
  if (int2my_decimal(E_DEC_FATAL_ERROR, date, false, dec))
323
 
    return dec;
324
 
  if (ltime->second_part)
325
 
  {
326
 
    dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
327
 
    dec->frac= 6;
328
 
  }
329
 
  return dec;
330
 
}
331
 
 
332
 
 
333
 
void my_decimal_trim(uint32_t *precision, uint32_t *scale)
334
 
{
335
 
  if (!(*precision) && !(*scale))
336
 
  {
337
 
    *precision= 10;
338
 
    *scale= 0;
339
 
    return;
340
 
  }
341
 
}
342
 
 
343
120
 
344
121
/*
345
122
  Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
363
140
#define DIG_MASK     100000000
364
141
#define DIG_BASE     1000000000
365
142
#define DIG_MAX      (DIG_BASE-1)
366
 
 
367
 
template<typename T> 
368
 
inline static T round_up(const T &x)
369
 
{
370
 
  return (x+DIG_PER_DEC1-1)/DIG_PER_DEC1;
371
 
}
372
 
 
 
143
#define ROUND_UP(X)  (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
373
144
static const dec1 powers10[DIG_PER_DEC1+1]={
374
145
  1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
375
146
static const int dig2bytes[DIG_PER_DEC1+1]={0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
378
149
  999900000, 999990000, 999999000,
379
150
  999999900, 999999990 };
380
151
 
381
 
#ifdef HAVE_VALGRIND
 
152
#ifdef HAVE_purify
382
153
#define sanity(d) assert((d)->len > 0)
383
154
#else
384
155
#define sanity(d) assert((d)->len >0 && ((d)->buf[0] | \
385
156
                              (d)->buf[(d)->len-1] | 1))
386
157
#endif
387
158
 
388
 
inline static void fix_intg_frac_error(const int len, int &intg1, int &frac1, int &error)
389
 
{
390
 
  if (unlikely(intg1+frac1 > len))
391
 
  {
392
 
    if (unlikely(intg1 > len))
393
 
    {
394
 
      intg1=(len);
395
 
      frac1=0;
396
 
      error=E_DEC_OVERFLOW;
397
 
    }
398
 
    else
399
 
    {
400
 
      frac1=(len)-intg1;
401
 
      error=E_DEC_TRUNCATED;
402
 
    }
403
 
  }
404
 
  else
405
 
    error=E_DEC_OK;
406
 
}
407
 
 
408
 
/* assume carry <= 1 */
409
 
inline static void add(dec1 &to, const dec1 &from1, const dec1& from2, dec1 &carry)
410
 
{
411
 
  dec1 a=from1+from2+carry;
412
 
  assert(carry <= 1);
413
 
  if ((carry= (a >= DIG_BASE))) /* no division here! */
414
 
    a-=DIG_BASE;
415
 
  to=a;
416
 
}
417
 
 
418
 
inline static void add2(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
419
 
{
420
 
  dec2 a=dec2(from1)+from2+carry;
421
 
  if ((carry= (a >= DIG_BASE)))
422
 
    a-=DIG_BASE;
423
 
  if (unlikely(a >= DIG_BASE))
424
 
  {
425
 
    a-=DIG_BASE;
426
 
    carry++;
427
 
  }
428
 
  to=dec1(a);
429
 
}
430
 
 
431
 
/* to=from1-from2 */
432
 
inline static void sub(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
433
 
{
434
 
  dec1 a=from1-from2-carry;
435
 
  if ((carry= (a < 0)))
436
 
    a+=DIG_BASE;
437
 
  to=a;
438
 
}
439
 
 
440
 
/* to=from1-from2 */
441
 
inline static void sub2(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
442
 
{
443
 
  dec1 a=from1-from2-carry;
444
 
  if ((carry= (a < 0)))
445
 
    a+=DIG_BASE;
446
 
  if (unlikely(a < 0))
447
 
  {
448
 
    a+=DIG_BASE;
449
 
    carry++;
450
 
  }
451
 
  to=a;
452
 
}
 
159
#define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error)                   \
 
160
        do                                                              \
 
161
        {                                                               \
 
162
          if (unlikely(intg1+frac1 > (len)))                            \
 
163
          {                                                             \
 
164
            if (unlikely(intg1 > (len)))                                \
 
165
            {                                                           \
 
166
              intg1=(len);                                              \
 
167
              frac1=0;                                                  \
 
168
              error=E_DEC_OVERFLOW;                                     \
 
169
            }                                                           \
 
170
            else                                                        \
 
171
            {                                                           \
 
172
              frac1=(len)-intg1;                                        \
 
173
              error=E_DEC_TRUNCATED;                                    \
 
174
            }                                                           \
 
175
          }                                                             \
 
176
          else                                                          \
 
177
            error=E_DEC_OK;                                             \
 
178
        } while(0)
 
179
 
 
180
#define ADD(to, from1, from2, carry)  /* assume carry <= 1 */           \
 
181
        do                                                              \
 
182
        {                                                               \
 
183
          dec1 a=(from1)+(from2)+(carry);                               \
 
184
          assert((carry) <= 1);                                    \
 
185
          if (((carry)= a >= DIG_BASE)) /* no division here! */         \
 
186
            a-=DIG_BASE;                                                \
 
187
          (to)=a;                                                       \
 
188
        } while(0)
 
189
 
 
190
#define ADD2(to, from1, from2, carry)                                   \
 
191
        do                                                              \
 
192
        {                                                               \
 
193
          dec2 a=((dec2)(from1))+(from2)+(carry);                       \
 
194
          if (((carry)= a >= DIG_BASE))                                 \
 
195
            a-=DIG_BASE;                                                \
 
196
          if (unlikely(a >= DIG_BASE))                                  \
 
197
          {                                                             \
 
198
            a-=DIG_BASE;                                                \
 
199
            carry++;                                                    \
 
200
          }                                                             \
 
201
          (to)=(dec1) a;                                                \
 
202
        } while(0)
 
203
 
 
204
#define SUB(to, from1, from2, carry) /* to=from1-from2 */               \
 
205
        do                                                              \
 
206
        {                                                               \
 
207
          dec1 a=(from1)-(from2)-(carry);                               \
 
208
          if (((carry)= a < 0))                                         \
 
209
            a+=DIG_BASE;                                                \
 
210
          (to)=a;                                                       \
 
211
        } while(0)
 
212
 
 
213
#define SUB2(to, from1, from2, carry) /* to=from1-from2 */              \
 
214
        do                                                              \
 
215
        {                                                               \
 
216
          dec1 a=(from1)-(from2)-(carry);                               \
 
217
          if (((carry)= a < 0))                                         \
 
218
            a+=DIG_BASE;                                                \
 
219
          if (unlikely(a < 0))                                          \
 
220
          {                                                             \
 
221
            a+=DIG_BASE;                                                \
 
222
            carry++;                                                    \
 
223
          }                                                             \
 
224
          (to)=a;                                                       \
 
225
        } while(0)
453
226
 
454
227
/**
455
 
  @brief  Get maximum value for given precision and scale
456
 
 
457
 
  @param  precision/scale  see decimal_bin_size() below
458
 
  @param  to              decimal where where the result will be stored
 
228
  Swap the contents of two variables.
 
229
 */
 
230
#define swap_variables(TYPE, a, b) \
 
231
  do {                             \
 
232
    TYPE dummy;                    \
 
233
    dummy= a;                      \
 
234
    a= b;                          \
 
235
    b= dummy;                      \
 
236
  } while (0)
 
237
 
 
238
 
 
239
/*
 
240
  Get maximum value for given precision and scale
 
241
 
 
242
  SYNOPSIS
 
243
    max_decimal()
 
244
    precision/scale - see decimal_bin_size() below
 
245
    to              - decimal where where the result will be stored
459
246
                      to->buf and to->len must be set.
460
247
*/
461
248
 
509
296
}
510
297
 
511
298
 
512
 
/**
513
 
 @brief Count actual length of fraction part (without ending zeroes)
 
299
/*
 
300
  Count actual length of fraction part (without ending zeroes)
514
301
 
515
 
 @param from    number for processing
 
302
  SYNOPSIS
 
303
    decimal_actual_fraction()
 
304
    from    number for processing
516
305
*/
517
306
 
518
307
int decimal_actual_fraction(decimal_t *from)
519
308
{
520
309
  int frac= from->frac, i;
521
 
  dec1 *buf0= from->buf + round_up(from->intg) + round_up(frac) - 1;
 
310
  dec1 *buf0= from->buf + ROUND_UP(from->intg) + ROUND_UP(frac) - 1;
522
311
 
523
312
  if (frac == 0)
524
313
    return 0;
538
327
}
539
328
 
540
329
 
541
 
/**
542
 
 @brief  Convert decimal to its printable string representation
 
330
/*
 
331
  Convert decimal to its printable string representation
543
332
 
544
 
 @param  from       value to convert
545
 
 @param  to         points to buffer where string representation
546
 
                    should be stored
547
 
 @param  to_len     in:  size of to buffer
548
 
                    out: length of the actually written string
549
 
 @param  fixed_precision 0 if representation can be variable length and
 
333
  SYNOPSIS
 
334
    decimal2string()
 
335
      from            - value to convert
 
336
      to              - points to buffer where string representation
 
337
                        should be stored
 
338
      *to_len         - in:  size of to buffer
 
339
                        out: length of the actually written string
 
340
      fixed_precision - 0 if representation can be variable length and
550
341
                        fixed_decimals will not be checked in this case.
551
342
                        Put number as with fixed point position with this
552
343
                        number of digits (sign counted and decimal point is
553
344
                        counted)
554
 
 @param  fixed_decimals  number digits after point.
555
 
 @param  filler          character to fill gaps in case of fixed_precision > 0
 
345
      fixed_decimals  - number digits after point.
 
346
      filler          - character to fill gaps in case of fixed_precision > 0
556
347
 
557
 
 @return error code
558
 
   @retval E_DEC_OK
559
 
   @retval E_DEC_TRUNCATED
560
 
   @retval E_DEC_OVERFLOW
 
348
  RETURN VALUE
 
349
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
561
350
*/
 
351
 
562
352
int decimal2string(const decimal_t *from, char *to, int *to_len,
563
353
                   int fixed_precision, int fixed_decimals,
564
354
                   char filler)
623
413
  {
624
414
    char *s1= s + intg_len;
625
415
    fill= frac_len - frac;
626
 
    buf=buf0+round_up(intg);
 
416
    buf=buf0+ROUND_UP(intg);
627
417
    *s1++='.';
628
418
    for (; frac>0; frac-=DIG_PER_DEC1)
629
419
    {
648
438
  if (intg)
649
439
  {
650
440
    s+=intg;
651
 
    for (buf=buf0+round_up(intg); intg>0; intg-=DIG_PER_DEC1)
 
441
    for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
652
442
    {
653
443
      dec1 x=*--buf;
654
444
      for (i=min(intg, DIG_PER_DEC1); i; i--)
665
455
}
666
456
 
667
457
 
668
 
/**
669
 
 @brief  Return bounds of decimal digits in the number
 
458
/*
 
459
  Return bounds of decimal digits in the number
670
460
 
671
 
 @param  from  decimal number for processing
672
 
 @param  start_result  index (from 0 ) of first decimal digits will
673
 
                       be written by this address
674
 
 @param  end_result   index of position just after last decimal digit
 
461
  SYNOPSIS
 
462
    digits_bounds()
 
463
      from         - decimal number for processing
 
464
      start_result - index (from 0 ) of first decimal digits will
 
465
                     be written by this address
 
466
      end_result   - index of position just after last decimal digit
675
467
                     be written by this address
676
468
*/
 
469
 
677
470
static void digits_bounds(decimal_t *from, int *start_result, int *end_result)
678
471
{
679
472
  int start, stop, i;
680
473
  dec1 *buf_beg= from->buf;
681
 
  dec1 *end= from->buf + round_up(from->intg) + round_up(from->frac);
 
474
  dec1 *end= from->buf + ROUND_UP(from->intg) + ROUND_UP(from->frac);
682
475
  dec1 *buf_end= end - 1;
683
476
 
684
477
  /* find non-zero digit from number begining */
727
520
}
728
521
 
729
522
 
730
 
/**
731
 
 @param Left shift for alignment of data in buffer
732
 
 
733
 
 @param  dec     pointer to decimal number which have to be shifted
734
 
 @param  shift   number of decimal digits on which it should be shifted
735
 
 @param  beg     beginning of decimal digits (see digits_bounds())
736
 
 @param  end     end of decimal digits (see digits_bounds())
737
 
 
738
 
 @note
739
 
   Result fitting in the buffer should be garanted.
740
 
   'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
741
 
   
742
 
 @todo  Above note is unclear - is 'garanted' a typo for 'guaranteed'
743
 
 or 'granted'?
 
523
/*
 
524
  Left shift for alignment of data in buffer
 
525
 
 
526
  SYNOPSIS
 
527
    do_mini_left_shift()
 
528
    dec     pointer to decimal number which have to be shifted
 
529
    shift   number of decimal digits on which it should be shifted
 
530
    beg/end bounds of decimal digits (see digits_bounds())
 
531
 
 
532
  NOTE
 
533
    Result fitting in the buffer should be garanted.
 
534
    'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
744
535
*/
 
536
 
745
537
static void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
746
538
{
747
 
  dec1 *from= dec->buf + round_up(beg + 1) - 1;
748
 
  dec1 *end= dec->buf + round_up(last) - 1;
 
539
  dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
 
540
  dec1 *end= dec->buf + ROUND_UP(last) - 1;
749
541
  int c_shift= DIG_PER_DEC1 - shift;
750
542
  assert(from >= dec->buf);
751
543
  assert(end < dec->buf + dec->len);
758
550
}
759
551
 
760
552
 
761
 
/**
762
 
  @brief Right shift for alignment of data in buffer
763
 
 
764
 
  @param  dec     pointer to decimal number which have to be shifted
765
 
  @param  shift   number of decimal digits on which it should be shifted
766
 
  @param  beg     beginning of decimal digits (see digits_bounds())
767
 
  @param  end     end of decimal digits (see digits_bounds())
768
 
 
769
 
  @note
 
553
/*
 
554
  Right shift for alignment of data in buffer
 
555
 
 
556
  SYNOPSIS
 
557
    do_mini_left_shift()
 
558
    dec     pointer to decimal number which have to be shifted
 
559
    shift   number of decimal digits on which it should be shifted
 
560
    beg/end bounds of decimal digits (see digits_bounds())
 
561
 
 
562
  NOTE
770
563
    Result fitting in the buffer should be garanted.
771
564
    'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
772
565
*/
 
566
 
773
567
static void do_mini_right_shift(decimal_t *dec, int shift, int beg, int last)
774
568
{
775
 
  dec1 *from= dec->buf + round_up(last) - 1;
776
 
  dec1 *end= dec->buf + round_up(beg + 1) - 1;
 
569
  dec1 *from= dec->buf + ROUND_UP(last) - 1;
 
570
  dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1;
777
571
  int c_shift= DIG_PER_DEC1 - shift;
778
572
  assert(from < dec->buf + dec->len);
779
573
  assert(end >= dec->buf);
786
580
}
787
581
 
788
582
 
789
 
/**
790
 
  @brief  Shift of decimal digits in given number (with rounding if it need)
 
583
/*
 
584
  Shift of decimal digits in given number (with rounding if it need)
791
585
 
792
 
  @param  dec       number to be shifted
793
 
  @param  shift     number of decimal positions
 
586
  SYNOPSIS
 
587
    decimal_shift()
 
588
    dec       number to be shifted
 
589
    shift     number of decimal positions
794
590
              shift > 0 means shift to left shift
795
591
              shift < 0 meand right shift
796
 
 
797
 
  @note
 
592
  NOTE
798
593
    In fact it is multipling on 10^shift.
 
594
  RETURN
 
595
    E_DEC_OK          OK
 
596
    E_DEC_OVERFLOW    operation lead to overflow, number is untoched
 
597
    E_DEC_TRUNCATED   number was rounded to fit into buffer
 
598
*/
799
599
 
800
 
  @return  Error code
801
 
   @retval E_DEC_OK          OK
802
 
   @retval E_DEC_OVERFLOW    operation lead to overflow, number is untoched
803
 
   @retval E_DEC_TRUNCATED   number was rounded to fit into buffer
804
 
*/
805
600
static int decimal_shift(decimal_t *dec, int shift)
806
601
{
807
602
  /* index of first non zero digit (all indexes from 0) */
809
604
  /* index of position after last decimal digit */
810
605
  int end;
811
606
  /* index of digit position just after point */
812
 
  int point= round_up(dec->intg) * DIG_PER_DEC1;
 
607
  int point= ROUND_UP(dec->intg) * DIG_PER_DEC1;
813
608
  /* new point position */
814
609
  int new_point= point + shift;
815
610
  /* number of digits in result */
836
631
  digits_frac= end - new_point;
837
632
  set_if_bigger(digits_frac, 0);
838
633
 
839
 
  if ((new_len= round_up(digits_int) + (new_frac_len= round_up(digits_frac))) >
 
634
  if ((new_len= ROUND_UP(digits_int) + (new_frac_len= ROUND_UP(digits_frac))) >
840
635
      dec->len)
841
636
  {
842
637
    int lack= new_len - dec->len;
896
691
    if (do_left)
897
692
    {
898
693
      do_mini_left_shift(dec, l_mini_shift, beg, end);
899
 
      mini_shift= (-l_mini_shift);
 
694
      mini_shift=- l_mini_shift;
900
695
    }
901
696
    else
902
697
    {
929
724
    {
930
725
      /* move left */
931
726
      d_shift= new_front / DIG_PER_DEC1;
932
 
      to= dec->buf + (round_up(beg + 1) - 1 - d_shift);
933
 
      barier= dec->buf + (round_up(end) - 1 - d_shift);
 
727
      to= dec->buf + (ROUND_UP(beg + 1) - 1 - d_shift);
 
728
      barier= dec->buf + (ROUND_UP(end) - 1 - d_shift);
934
729
      assert(to >= dec->buf);
935
730
      assert(barier + d_shift < dec->buf + dec->len);
936
731
      for(; to <= barier; to++)
943
738
    {
944
739
      /* move right */
945
740
      d_shift= (1 - new_front) / DIG_PER_DEC1;
946
 
      to= dec->buf + round_up(end) - 1 + d_shift;
947
 
      barier= dec->buf + round_up(beg + 1) - 1 + d_shift;
 
741
      to= dec->buf + ROUND_UP(end) - 1 + d_shift;
 
742
      barier= dec->buf + ROUND_UP(beg + 1) - 1 + d_shift;
948
743
      assert(to < dec->buf + dec->len);
949
744
      assert(barier - d_shift >= dec->buf);
950
745
      for(; to >= barier; to--)
963
758
 
964
759
    Only one of following 'for' loops will work becouse beg <= end
965
760
  */
966
 
  beg= round_up(beg + 1) - 1;
967
 
  end= round_up(end) - 1;
 
761
  beg= ROUND_UP(beg + 1) - 1;
 
762
  end= ROUND_UP(end) - 1;
968
763
  assert(new_point >= 0);
969
764
 
970
765
  /* We don't want negative new_point below */
971
766
  if (new_point != 0)
972
 
    new_point= round_up(new_point) - 1;
 
767
    new_point= ROUND_UP(new_point) - 1;
973
768
 
974
769
  if (new_point > end)
975
770
  {
989
784
}
990
785
 
991
786
 
992
 
/**
993
 
  @brief  Convert string to decimal
 
787
/*
 
788
  Convert string to decimal
994
789
 
995
 
  @param  from    value to convert. Doesn't have to be \0 terminated!
996
 
  @param  to      decimal where where the result will be stored
 
790
  SYNOPSIS
 
791
    internal_str2decl()
 
792
      from    - value to convert. Doesn't have to be \0 terminated!
 
793
      to      - decimal where where the result will be stored
997
794
                to->buf and to->len must be set.
998
 
  @param  end     Pointer to pointer to end of string. Will on return be
 
795
      end     - Pointer to pointer to end of string. Will on return be
999
796
                set to the char after the last used character
1000
 
  @param  fixed   use to->intg, to->frac as limits for input number
 
797
      fixed   - use to->intg, to->frac as limits for input number
1001
798
 
1002
 
  @note
 
799
  NOTE
1003
800
    to->intg and to->frac can be modified even when fixed=1
1004
801
    (but only decreased, in this case)
1005
802
 
1006
 
  @return
 
803
  RETURN VALUE
1007
804
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_BAD_NUM/E_DEC_OOM
1008
805
    In case of E_DEC_FATAL_ERROR *to is set to decimal zero
1009
806
    (to make error handling easier)
1010
807
*/
 
808
 
1011
809
int
1012
810
internal_str2dec(char *from, decimal_t *to, char **end, bool fixed)
1013
811
{
1064
862
      error=E_DEC_OVERFLOW;
1065
863
      intg=to->intg;
1066
864
    }
1067
 
    intg1=round_up(intg);
1068
 
    frac1=round_up(frac);
 
865
    intg1=ROUND_UP(intg);
 
866
    frac1=ROUND_UP(frac);
1069
867
    if (intg1+frac1 > to->len)
1070
868
    {
1071
869
      error= E_DEC_OOM;
1074
872
  }
1075
873
  else
1076
874
  {
1077
 
    intg1=round_up(intg);
1078
 
    frac1=round_up(frac);
1079
 
    fix_intg_frac_error(to->len, intg1, frac1, error);
 
875
    intg1=ROUND_UP(intg);
 
876
    frac1=ROUND_UP(frac);
 
877
    FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
1080
878
    if (unlikely(error))
1081
879
    {
1082
880
      frac=frac1*DIG_PER_DEC1;
1157
955
}
1158
956
 
1159
957
 
1160
 
/**
1161
 
  @param Convert decimal to double
1162
 
 
1163
 
  @param[in]   from   value to convert
1164
 
  @param[out]  to     result will be stored there
1165
 
 
1166
 
  @return
 
958
/*
 
959
  Convert decimal to double
 
960
 
 
961
  SYNOPSIS
 
962
    decimal2double()
 
963
      from    - value to convert
 
964
      to      - result will be stored there
 
965
 
 
966
  RETURN VALUE
1167
967
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1168
968
*/
1169
969
 
1181
981
  return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
1182
982
}
1183
983
 
1184
 
/**
1185
 
 @param  Convert double to decimal
1186
 
 
1187
 
 @param[in]  from    value to convert
1188
 
 @param[out] to      result will be stored there
1189
 
 
1190
 
 @return
 
984
/*
 
985
  Convert double to decimal
 
986
 
 
987
  SYNOPSIS
 
988
    double2decimal()
 
989
      from    - value to convert
 
990
      to      - result will be stored there
 
991
 
 
992
  RETURN VALUE
1191
993
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1192
994
*/
1193
995
 
1311
1113
  return E_DEC_OK;
1312
1114
}
1313
1115
 
1314
 
/**
1315
 
 @brief
1316
 
  Convert decimal to its binary fixed-length representation (suitable for
1317
 
  comparing with memcmp)
1318
 
 
 
1116
/*
 
1117
  Convert decimal to its binary fixed-length representation
 
1118
  two representations of the same length can be compared with memcmp
 
1119
  with the correct -1/0/+1 result
 
1120
 
 
1121
  SYNOPSIS
 
1122
    decimal2bin()
 
1123
      from    - value to convert
 
1124
      to      - points to buffer where string representation should be stored
 
1125
      precision/scale - see decimal_bin_size() below
 
1126
 
 
1127
  NOTE
 
1128
    the buffer is assumed to be of the size decimal_bin_size(precision, scale)
 
1129
 
 
1130
  RETURN VALUE
 
1131
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
 
1132
 
 
1133
  DESCRIPTION
1319
1134
    for storage decimal numbers are converted to the "binary" format.
1320
1135
 
1321
1136
    This format has the following properties:
1376
1191
    And for -1234567890.1234 it would be
1377
1192
 
1378
1193
                7E F2 04 37 2D FB 2D
1379
 
 
1380
 
 
1381
 
  @param from      value to convert
1382
 
  @param to        points to buffer where string representation should be stored
1383
 
  @param precision see decimal_bin_size() below
1384
 
  @param frac      see decimal_bin_size() below
1385
 
 
1386
 
  @note
1387
 
    The buffer is assumed to be of the size decimal_bin_size(precision, scale)
1388
 
 
1389
 
  @return
1390
 
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1391
 
 
1392
1194
*/
1393
1195
int decimal2bin(const decimal_t *from, unsigned char *to, int precision, int frac)
1394
1196
{
1508
1310
  return error;
1509
1311
}
1510
1312
 
1511
 
/**
1512
 
 @brief Restores decimal from its binary fixed-length representation
1513
 
 
1514
 
 @param  from    value to convert
1515
 
 @param  to      result
1516
 
 @param  precision see decimal_bin_size() below
1517
 
 @param  scale     see decimal_bin_size() below
1518
 
 
1519
 
 @note
 
1313
/*
 
1314
  Restores decimal from its binary fixed-length representation
 
1315
 
 
1316
  SYNOPSIS
 
1317
    bin2decimal()
 
1318
      from    - value to convert
 
1319
      to      - result
 
1320
      precision/scale - see decimal_bin_size() below
 
1321
 
 
1322
  NOTE
1520
1323
    see decimal2bin()
1521
1324
    the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1522
1325
 
1523
 
 @return
 
1326
  RETURN VALUE
1524
1327
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1525
1328
*/
 
1329
 
1526
1330
int bin2decimal(const unsigned char *from, decimal_t *to, int precision, int scale)
1527
1331
{
1528
1332
  int error=E_DEC_OK, intg=precision-scale,
1540
1344
  d_copy[0]^= 0x80;
1541
1345
  from= d_copy;
1542
1346
 
1543
 
  fix_intg_frac_error(to->len, intg1, frac1, error);
 
1347
  FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
1544
1348
  if (unlikely(error))
1545
1349
  {
1546
1350
    if (intg1 < intg0+(intg0x>0))
1625
1429
  return(E_DEC_BAD_NUM);
1626
1430
}
1627
1431
 
1628
 
/**
1629
 
 @brief  Returns the size of array to hold a binary representation of a decimal
 
1432
/*
 
1433
  Returns the size of array to hold a binary representation of a decimal
1630
1434
 
1631
 
 @return  Size in bytes
 
1435
  RETURN VALUE
 
1436
    size in bytes
1632
1437
*/
 
1438
 
1633
1439
int decimal_bin_size(int precision, int scale)
1634
1440
{
1635
1441
  int intg=precision-scale,
1641
1447
         frac0*sizeof(dec1)+dig2bytes[frac0x];
1642
1448
}
1643
1449
 
1644
 
/**
1645
 
 @brief  Rounds the decimal to "scale" digits
1646
 
 
1647
 
 @param from    - decimal to round,
1648
 
 @param to      - result buffer. from==to is allowed
1649
 
 @param scale   - to what position to round. can be negative!
1650
 
 @param mode    - round to nearest even or truncate
1651
 
 
1652
 
 @note
 
1450
/*
 
1451
  Rounds the decimal to "scale" digits
 
1452
 
 
1453
  SYNOPSIS
 
1454
    decimal_round()
 
1455
      from    - decimal to round,
 
1456
      to      - result buffer. from==to is allowed
 
1457
      scale   - to what position to round. can be negative!
 
1458
      mode    - round to nearest even or truncate
 
1459
 
 
1460
  NOTES
1653
1461
    scale can be negative !
1654
1462
    one TRUNCATED error (line XXX below) isn't treated very logical :(
1655
1463
 
1656
 
 @return
 
1464
  RETURN VALUE
1657
1465
    E_DEC_OK/E_DEC_TRUNCATED
1658
1466
*/
 
1467
 
1659
1468
int
1660
1469
decimal_round(const decimal_t *from, decimal_t *to, int scale,
1661
1470
              decimal_round_mode mode)
1662
1471
{
1663
 
  int frac0=scale>0 ? round_up(scale) : scale/DIG_PER_DEC1,
1664
 
      frac1=round_up(from->frac), round_digit= 0,
1665
 
      intg0=round_up(from->intg), error=E_DEC_OK, len=to->len,
1666
 
      intg1=round_up(from->intg +
 
1472
  int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
 
1473
      frac1=ROUND_UP(from->frac), round_digit= 0,
 
1474
      intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len,
 
1475
      intg1=ROUND_UP(from->intg +
1667
1476
                     (((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX)));
1668
1477
  dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
1669
1478
  int first_dig;
1765
1574
  }
1766
1575
  else
1767
1576
  {
1768
 
  /** @todo fix this code as it won't work for CEILING mode */
 
1577
    /* TODO - fix this code as it won't work for CEILING mode */
1769
1578
    int pos=frac0*DIG_PER_DEC1-scale-1;
1770
1579
    assert(frac0+intg0 > 0);
1771
1580
    x=*buf1 / powers10[pos];
1798
1607
    carry=1;
1799
1608
    *buf1-=DIG_BASE;
1800
1609
    while (carry && --buf1 >= to->buf)
1801
 
      add(*buf1, *buf1, 0, carry);
 
1610
      ADD(*buf1, *buf1, 0, carry);
1802
1611
    if (unlikely(carry))
1803
1612
    {
1804
1613
      /* shifting the number to create space for new digit */
1851
1660
 
1852
1661
static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1853
1662
{
1854
 
  int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
1855
 
      frac1=round_up(from1->frac), frac2=round_up(from2->frac),
 
1663
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
 
1664
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1856
1665
      frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
1857
1666
  dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
1858
1667
 
1868
1677
    to->buf[0]=0; /* safety */
1869
1678
  }
1870
1679
 
1871
 
  fix_intg_frac_error(to->len, intg0, frac0, error);
 
1680
  FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
1872
1681
  if (unlikely(error == E_DEC_OVERFLOW))
1873
1682
  {
1874
1683
    max_decimal(to->len * DIG_PER_DEC1, 0, to);
1911
1720
  carry=0;
1912
1721
  while (buf1 > stop2)
1913
1722
  {
1914
 
    add(*--buf0, *--buf1, *--buf2, carry);
 
1723
    ADD(*--buf0, *--buf1, *--buf2, carry);
1915
1724
  }
1916
1725
 
1917
1726
  /* part 3 - cmin(intg) ... cmax(intg) */
1919
1728
                        ((stop=from2->buf)+intg2-intg1) ;
1920
1729
  while (buf1 > stop)
1921
1730
  {
1922
 
    add(*--buf0, *--buf1, 0, carry);
 
1731
    ADD(*--buf0, *--buf1, 0, carry);
1923
1732
  }
1924
1733
 
1925
1734
  if (unlikely(carry))
1933
1742
   if to==0, return -1/0/+1 - the result of the comparison */
1934
1743
static int do_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1935
1744
{
1936
 
  int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
1937
 
      frac1=round_up(from1->frac), frac2=round_up(from2->frac);
 
1745
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
 
1746
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
1938
1747
  int frac0=max(frac1, frac2), error;
1939
1748
  dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
1940
1749
 
2000
1809
  /* ensure that always from1 > from2 (and intg1 >= intg2) */
2001
1810
  if (carry)
2002
1811
  {
2003
 
    swap(from1, from2);
2004
 
    swap(start1, start2);
2005
 
    swap(intg1, intg2);
2006
 
    swap(frac1, frac2);
 
1812
    swap_variables(const decimal_t *,from1, from2);
 
1813
    swap_variables(dec1 *,start1, start2);
 
1814
    swap_variables(int,intg1,intg2);
 
1815
    swap_variables(int,frac1,frac2);
2007
1816
    to->sign= 1 - to->sign;
2008
1817
  }
2009
1818
 
2010
 
  fix_intg_frac_error(to->len, intg1, frac0, error);
 
1819
  FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
2011
1820
  buf0=to->buf+intg1+frac0;
2012
1821
 
2013
1822
  to->frac=max(from1->frac, from2->frac);
2041
1850
      *--buf0=0;
2042
1851
    while (buf2 > stop2)
2043
1852
    {
2044
 
      sub(*--buf0, 0, *--buf2, carry);
 
1853
      SUB(*--buf0, 0, *--buf2, carry);
2045
1854
    }
2046
1855
  }
2047
1856
 
2048
1857
  /* part 2 - cmin(frac) ... intg2 */
2049
1858
  while (buf2 > start2)
2050
1859
  {
2051
 
    sub(*--buf0, *--buf1, *--buf2, carry);
 
1860
    SUB(*--buf0, *--buf1, *--buf2, carry);
2052
1861
  }
2053
1862
 
2054
1863
  /* part 3 - intg2 ... intg1 */
2055
1864
  while (carry && buf1 > start1)
2056
1865
  {
2057
 
    sub(*--buf0, *--buf1, 0, carry);
 
1866
    SUB(*--buf0, *--buf1, 0, carry);
2058
1867
  }
2059
1868
 
2060
1869
  while (buf1 > start1)
2098
1907
int decimal_is_zero(const decimal_t *from)
2099
1908
{
2100
1909
  dec1 *buf1=from->buf,
2101
 
       *end=buf1+round_up(from->intg)+round_up(from->frac);
 
1910
       *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2102
1911
  while (buf1 < end)
2103
1912
    if (*buf1++)
2104
1913
      return 0;
2105
1914
  return 1;
2106
1915
}
2107
1916
 
2108
 
/**
2109
 
 @brief multiply two decimals
2110
 
 
2111
 
 @param[in]   from1  First factor
2112
 
 @param[in]   from2  Second factor
2113
 
 @param[out]  to     product
2114
 
 
2115
 
 @return
 
1917
/*
 
1918
  multiply two decimals
 
1919
 
 
1920
  SYNOPSIS
 
1921
    decimal_mul()
 
1922
      from1, from2 - factors
 
1923
      to      - product
 
1924
 
 
1925
  RETURN VALUE
2116
1926
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
2117
1927
 
2118
 
 @note
 
1928
  NOTES
2119
1929
    in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
2120
1930
    and 63-digit number will take only 7 dec1 words (basically a 7-digit
2121
1931
    "base 999999999" number).  Thus there's no need in fast multiplication
2127
1937
*/
2128
1938
int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2129
1939
{
2130
 
  int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
2131
 
      frac1=round_up(from1->frac), frac2=round_up(from2->frac),
2132
 
      intg0=round_up(from1->intg+from2->intg),
 
1940
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
 
1941
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
 
1942
      intg0=ROUND_UP(from1->intg+from2->intg),
2133
1943
      frac0=frac1+frac2, error, i, j, d_to_move;
2134
1944
  dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
2135
1945
       *start2, *stop2, *stop1, *start0, carry;
2138
1948
 
2139
1949
  i=intg0;
2140
1950
  j=frac0;
2141
 
  fix_intg_frac_error(to->len, intg0, frac0, error);
 
1951
  FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2142
1952
  to->sign=from1->sign != from2->sign;
2143
1953
  to->frac=from1->frac+from2->frac;
2144
1954
  to->intg=intg0*DIG_PER_DEC1;
2179
1989
      dec2 p= ((dec2)*buf1) * ((dec2)*buf2);
2180
1990
      hi=(dec1)(p/DIG_BASE);
2181
1991
      lo=(dec1)(p-((dec2)hi)*DIG_BASE);
2182
 
      add2(*buf0, *buf0, lo, carry);
 
1992
      ADD2(*buf0, *buf0, lo, carry);
2183
1993
      carry+=hi;
2184
1994
    }
2185
1995
    if (carry)
2186
1996
    {
2187
1997
      if (buf0 < to->buf)
2188
1998
        return E_DEC_OVERFLOW;
2189
 
      add2(*buf0, *buf0, 0, carry);
 
1999
      ADD2(*buf0, *buf0, 0, carry);
2190
2000
    }
2191
2001
    for (buf0--; carry; buf0--)
2192
2002
    {
2193
2003
      if (buf0 < to->buf)
2194
2004
        return E_DEC_OVERFLOW;
2195
 
      add(*buf0, *buf0, 0, carry);
 
2005
      ADD(*buf0, *buf0, 0, carry);
2196
2006
    }
2197
2007
  }
2198
2008
 
2215
2025
    }
2216
2026
  }
2217
2027
  buf1= to->buf;
2218
 
  d_to_move= intg0 + round_up(to->frac);
 
2028
  d_to_move= intg0 + ROUND_UP(to->frac);
2219
2029
  while (!*buf1 && (to->intg > DIG_PER_DEC1))
2220
2030
  {
2221
2031
    buf1++;
2231
2041
  return error;
2232
2042
}
2233
2043
 
2234
 
/**
 
2044
/*
2235
2045
  naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2236
2046
  it's ok for short numbers
2237
2047
  also we're using alloca() to allocate a temporary buffer
2238
2048
 
2239
 
  @todo
2240
 
  If this library is to be used with huge numbers of thousands of
 
2049
  XXX if this library is to be used with huge numbers of thousands of
2241
2050
  digits, fast division must be implemented and alloca should be
2242
2051
  changed to malloc (or at least fallback to malloc if alloca() fails)
2243
2052
  but then, decimal_mul() should be rewritten too :(
2245
2054
static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2246
2055
                       decimal_t *to, decimal_t *mod, int scale_incr)
2247
2056
{
2248
 
  int frac1=round_up(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2249
 
      frac2=round_up(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
 
2057
  int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
 
2058
      frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2250
2059
      error= 0, i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2251
2060
  dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2252
2061
       *start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
2296
2105
    intg0=0;
2297
2106
  }
2298
2107
  else
2299
 
    intg0=round_up(dintg);
 
2108
    intg0=ROUND_UP(dintg);
2300
2109
  if (mod)
2301
2110
  {
2302
2111
    /* we're calculating N1 % N2.
2315
2124
      N2 is in the buf2, has prec2 digits. Scales are frac1 and
2316
2125
      frac2 accordingly.
2317
2126
      Thus, the result will have
2318
 
         frac = round_up(frac1+frac2+scale_incr)
 
2127
         frac = ROUND_UP(frac1+frac2+scale_incr)
2319
2128
      and
2320
2129
         intg = (prec1-frac1) - (prec2-frac2) + 1
2321
2130
         prec = intg+frac
2322
2131
    */
2323
 
    frac0=round_up(frac1+frac2+scale_incr);
2324
 
    fix_intg_frac_error(to->len, intg0, frac0, error);
 
2132
    frac0=ROUND_UP(frac1+frac2+scale_incr);
 
2133
    FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2325
2134
    to->sign=from1->sign != from2->sign;
2326
2135
    to->intg=intg0*DIG_PER_DEC1;
2327
2136
    to->frac=frac0*DIG_PER_DEC1;
2332
2141
    while (dintg++ < 0)
2333
2142
      *buf0++=0;
2334
2143
 
2335
 
  len1=(i=round_up(prec1))+round_up(2*frac2+scale_incr+1) + 1;
 
2144
  len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1;
2336
2145
  set_if_bigger(len1, 3);
2337
2146
  if (!(tmp1=(dec1 *)alloca(len1*sizeof(dec1))))
2338
2147
    return E_DEC_OOM;
2342
2151
  start1=tmp1;
2343
2152
  stop1=start1+len1;
2344
2153
  start2=buf2;
2345
 
  stop2=buf2+round_up(prec2)-1;
 
2154
  stop2=buf2+ROUND_UP(prec2)-1;
2346
2155
 
2347
2156
  /* removing end zeroes */
2348
2157
  while (*stop2 == 0 && stop2 >= start2)
2401
2210
        x=guess * (*--buf2);
2402
2211
        hi=(dec1)(x/DIG_BASE);
2403
2212
        lo=(dec1)(x-((dec2)hi)*DIG_BASE);
2404
 
        sub2(*buf1, *buf1, lo, carry);
 
2213
        SUB2(*buf1, *buf1, lo, carry);
2405
2214
        carry+=hi;
2406
2215
      }
2407
2216
      carry= dcarry < carry;
2415
2224
        buf1=start1+len2;
2416
2225
        for (carry=0; buf2 > start2; buf1--)
2417
2226
        {
2418
 
          add(*buf1, *buf1, *--buf2, carry);
 
2227
          ADD(*buf1, *buf1, *--buf2, carry);
2419
2228
        }
2420
2229
      }
2421
2230
    }
2434
2243
    if (dcarry)
2435
2244
      *--start1=dcarry;
2436
2245
    buf0=to->buf;
2437
 
    intg0=(int) (round_up(prec1-frac1)-(start1-tmp1));
2438
 
    frac0=round_up(to->frac);
 
2246
    intg0=(int) (ROUND_UP(prec1-frac1)-(start1-tmp1));
 
2247
    frac0=ROUND_UP(to->frac);
2439
2248
    error=E_DEC_OK;
2440
2249
    if (unlikely(frac0==0 && intg0==0))
2441
2250
    {
2465
2274
        error=E_DEC_OVERFLOW;
2466
2275
        goto done;
2467
2276
      }
2468
 
      assert(intg0 <= round_up(from2->intg));
 
2277
      assert(intg0 <= ROUND_UP(from2->intg));
2469
2278
      stop1=start1+frac0+intg0;
2470
2279
      to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
2471
2280
    }
2484
2293
  return error;
2485
2294
}
2486
2295
 
2487
 
/**
2488
 
 @brief  division of two decimals
2489
 
 
2490
 
 @param[in]  from1   dividend
2491
 
 @param[in]  from2   divisor
2492
 
 @param[out] to      quotient
2493
 
 
2494
 
 @return
 
2296
/*
 
2297
  division of two decimals
 
2298
 
 
2299
  SYNOPSIS
 
2300
    decimal_div()
 
2301
      from1   - dividend
 
2302
      from2   - divisor
 
2303
      to      - quotient
 
2304
 
 
2305
  RETURN VALUE
2495
2306
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2496
2307
 
2497
 
 @note
 
2308
  NOTES
2498
2309
    see do_div_mod()
2499
2310
*/
 
2311
 
2500
2312
int
2501
2313
decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
2502
2314
{
2503
2315
  return do_div_mod(from1, from2, to, 0, scale_incr);
2504
2316
}
2505
2317
 
2506
 
/**
2507
 
 @brief modulus
2508
 
 
2509
 
 the modulus R in    R = M mod N
2510
 
 
2511
 
 is defined as
2512
 
 
2513
 
 0 <= |R| < |M|
2514
 
 sign R == sign M
2515
 
 R = M - k*N, where k is integer
2516
 
 
2517
 
 thus, there's no requirement for M or N to be integers
2518
 
 
2519
 
 
2520
 
 @param from1   dividend
2521
 
 @param from2   divisor
2522
 
 @param to      modulus
2523
 
 
2524
 
 @return
 
2318
/*
 
2319
  modulus
 
2320
 
 
2321
  SYNOPSIS
 
2322
    decimal_mod()
 
2323
      from1   - dividend
 
2324
      from2   - divisor
 
2325
      to      - modulus
 
2326
 
 
2327
  RETURN VALUE
2525
2328
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2526
2329
 
2527
 
 @note
 
2330
  NOTES
2528
2331
    see do_div_mod()
2529
2332
 
 
2333
  DESCRIPTION
 
2334
    the modulus R in    R = M mod N
 
2335
 
 
2336
   is defined as
 
2337
 
 
2338
     0 <= |R| < |M|
 
2339
     sign R == sign M
 
2340
     R = M - k*N, where k is integer
 
2341
 
 
2342
   thus, there's no requirement for M or N to be integers
2530
2343
*/
 
2344
 
2531
2345
int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2532
2346
{
2533
2347
  return do_div_mod(from1, from2, 0, to, 0);
2545
2359
{
2546
2360
  int i;
2547
2361
  printf("/* intg=%d, frac=%d, sign=%d, buf[]={", d->intg, d->frac, d->sign);
2548
 
  for (i=0; i < round_up(d->frac)+round_up(d->intg)-1; i++)
 
2362
  for (i=0; i < ROUND_UP(d->frac)+ROUND_UP(d->intg)-1; i++)
2549
2363
    printf("%09d, ", d->buf[i]);
2550
2364
  printf("%09d} */ ", d->buf[i]);
2551
2365
}
2617
2431
{
2618
2432
  char s1[100], *end;
2619
2433
  int res;
2620
 
  snprintf(s1, sizeof(s1), "'%s'", s);
 
2434
  sprintf(s1, "'%s'", s);
2621
2435
  end= strend(s);
2622
2436
  printf("len=%2d %-30s => res=%d    ", a.len, s1,
2623
2437
         (res= string2decimal(s, &a, &end)));
2631
2445
  double x;
2632
2446
  int res;
2633
2447
 
2634
 
  snprintf(s1, sizeof(s1), "'%s'", s);
 
2448
  sprintf(s1, "'%s'", s);
2635
2449
  end= strend(s);
2636
2450
  string2decimal(s, &a, &end);
2637
2451
  res=decimal2double(&a, &x);
2645
2459
  char s1[100], buf[100], *end;
2646
2460
  int res, i, size=decimal_bin_size(p, s);
2647
2461
 
2648
 
  snprintf(s1, sizeof(s1), "'%s'", str);
 
2462
  sprintf(s1, "'%s'", str);
2649
2463
  end= strend(str);
2650
2464
  string2decimal(str, &a, &end);
2651
2465
  res=decimal2bin(&a, buf, p, s);
2740
2554
{
2741
2555
  char s[100], *end;
2742
2556
  int res;
2743
 
  snprintf(s, sizeof(s), "'%s' + '%s'", s1, s2);
 
2557
  sprintf(s, "'%s' + '%s'", s1, s2);
2744
2558
  end= strend(s1);
2745
2559
  string2decimal(s1, &a, &end);
2746
2560
  end= strend(s2);
2755
2569
{
2756
2570
  char s[100], *end;
2757
2571
  int res;
2758
 
  snprintf(s, sizeof(s), "'%s' - '%s'", s1, s2);
 
2572
  sprintf(s, "'%s' - '%s'", s1, s2);
2759
2573
  end= strend(s1);
2760
2574
  string2decimal(s1, &a, &end);
2761
2575
  end= strend(s2);
2770
2584
{
2771
2585
  char s[100], *end;
2772
2586
  int res;
2773
 
  snprintf(s, sizeof(s), "'%s' <=> '%s'", s1, s2);
 
2587
  sprintf(s, "'%s' <=> '%s'", s1, s2);
2774
2588
  end= strend(s1);
2775
2589
  string2decimal(s1, &a, &end);
2776
2590
  end= strend(s2);
2788
2602
{
2789
2603
  char s[100], *end;
2790
2604
  int res;
2791
 
  snprintf(s, sizeof(s), "'%s' * '%s'", s1, s2);
 
2605
  sprintf(s, "'%s' * '%s'", s1, s2);
2792
2606
  end= strend(s1);
2793
2607
  string2decimal(s1, &a, &end);
2794
2608
  end= strend(s2);
2803
2617
{
2804
2618
  char s[100], *end;
2805
2619
  int res;
2806
 
  snprintf(s, sizeof(s), "'%s' / '%s'", s1, s2);
 
2620
  sprintf(s, "'%s' / '%s'", s1, s2);
2807
2621
  end= strend(s1);
2808
2622
  string2decimal(s1, &a, &end);
2809
2623
  end= strend(s2);
2822
2636
{
2823
2637
  char s[100], *end;
2824
2638
  int res;
2825
 
  snprintf(s, sizeof(s), "'%s' %% '%s'", s1, s2);
 
2639
  sprintf(s, "'%s' %% '%s'", s1, s2);
2826
2640
  end= strend(s1);
2827
2641
  string2decimal(s1, &a, &end);
2828
2642
  end= strend(s2);
2845
2659
{
2846
2660
  char s[100], *end;
2847
2661
  int res;
2848
 
  snprintf(s, sizeof(s), "'%s', %d, %s", s1, n, round_mode[mode]);
 
2662
  sprintf(s, "'%s', %d, %s", s1, n, round_mode[mode]);
2849
2663
  end= strend(s1);
2850
2664
  string2decimal(s1, &a, &end);
2851
2665
  res=decimal_round(&a, &b, n, mode);
2858
2672
void test_mx(int precision, int frac, const char *orig)
2859
2673
{
2860
2674
  char s[100];
2861
 
  snprintf(s, sizeof(s), "%d, %d", precision, frac);
 
2675
  sprintf(s, "%d, %d", precision, frac);
2862
2676
  max_decimal(precision, frac, &a);
2863
2677
  printf("%-40s =>          ", s);
2864
2678
  print_decimal(&a, orig, 0, 0);
2874
2688
  int slen= sizeof(s2);
2875
2689
  int res;
2876
2690
 
2877
 
  snprintf(s, sizeof(s), filler ? "'%s', %d, %d, '%c'" : "'%s', %d, %d, '\\0'",
 
2691
  sprintf(s, filler ? "'%s', %d, %d, '%c'" : "'%s', %d, %d, '\\0'",
2878
2692
          s1, prec, dec, filler);
2879
2693
  end= strend(s1);
2880
2694
  string2decimal(s1, &a, &end);
2894
2708
{
2895
2709
  char s[100], *end;
2896
2710
  int res;
2897
 
  snprintf(s, sizeof(s), "'%s' %s %d", s1, ((shift < 0) ? ">>" : "<<"), abs(shift));
 
2711
  sprintf(s, "'%s' %s %d", s1, ((shift < 0) ? ">>" : "<<"), abs(shift));
2898
2712
  end= strend(s1);
2899
2713
  string2decimal(s1, &a, &end);
2900
2714
  res= decimal_shift(&a, shift);
2907
2721
void test_fr(const char *s1, const char *orig)
2908
2722
{
2909
2723
  char s[100], *end;
2910
 
  snprintf(s, sizeof(s), "'%s'", s1);
 
2724
  sprintf(s, "'%s'", s1);
2911
2725
  printf("%-40s =>          ", s);
2912
2726
  end= strend(s1);
2913
2727
  string2decimal(s1, &a, &end);