~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/decimal.cc

  • Committer: Lee Bieber
  • Date: 2010-10-27 18:28:56 UTC
  • mfrom: (1883.1.3 build)
  • Revision ID: kalebral@gmail.com-20101027182856-q3wqtbv1t4egkjsk
Merge Andrew - fix bug 667360: --defaults-file not processed before paths read           
Merge Andrew - fix bug 656577: Importing SQL script results in silent failure    
Merge Andrew - fix bug 667053: drizzledump minor output cleanup needed

Show diffs side-by-side

added added

removed removed

Lines of Context:
108
108
#include "drizzled/definitions.h"
109
109
#include "drizzled/internal/m_string.h"
110
110
#include "drizzled/charset_info.h"
111
 
#include "drizzled/type/decimal.h"
 
111
#include "drizzled/decimal.h"
112
112
 
113
113
#include <plugin/myisam/myisampack.h>
114
114
#include <drizzled/util/test.h>
178
178
/**
179
179
  @brief Converting decimal to string
180
180
 
181
 
  @details Convert given type::Decimal to String; allocate buffer as needed.
 
181
  @details Convert given my_decimal to String; allocate buffer as needed.
182
182
 
183
183
  @param[in]   mask        what problems to warn on (mask of E_DEC_* values)
184
184
  @param[in]   d           the decimal to print
194
194
    @retval E_DEC_OOM
195
195
*/
196
196
 
197
 
int class_decimal2string(const type::Decimal *d,
198
 
                         uint32_t fixed_dec, String *str)
 
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)
199
200
{
200
 
  uint32_t mask= E_DEC_FATAL_ERROR;
201
 
 
202
201
  /*
203
202
    Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a
204
203
    holds true iff the type is also ZEROFILL, which in turn implies
207
206
    one if the user only wanted decimal places, but we force a leading
208
207
    zero on them. Because the type is implicitly UNSIGNED, we do not
209
208
    need to reserve a character for the sign. For all other cases,
210
 
    fixed_prec will be 0, and class_decimal_string_length() will be called
 
209
    fixed_prec will be 0, and my_decimal_string_length() will be called
211
210
    instead to calculate the required size of the buffer.
212
211
  */
213
 
  int length= (int)(0
214
 
                    ? (uint32_t)(((0 == fixed_dec) ? 1 : 0) + 1)
215
 
                    : (uint32_t)d->string_length());
 
212
  int length= (fixed_prec
 
213
               ? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
 
214
               : my_decimal_string_length(d));
216
215
  int result;
217
216
  if (str->alloc(length))
218
217
    return check_result(mask, E_DEC_OOM);
219
 
 
220
218
  result= decimal2string((decimal_t*) d, (char*) str->ptr(),
221
 
                         &length, (int)0, fixed_dec,
222
 
                         '0');
 
219
                         &length, (int)fixed_prec, fixed_dec,
 
220
                         filler);
223
221
  str->length(length);
224
222
  return check_result(mask, result);
225
223
}
244
242
   @retval E_DEC_OVERFLOW
245
243
*/
246
244
 
247
 
namespace type {
248
 
 
249
 
int Decimal::val_binary(uint32_t mask, unsigned char *bin, int prec, int scale) const
 
245
int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
 
246
                      int scale)
250
247
{
251
248
  int err1= E_DEC_OK, err2;
252
 
  type::Decimal rounded;
253
 
  class_decimal2decimal(this, &rounded);
 
249
  my_decimal rounded;
 
250
  my_decimal2decimal(d, &rounded);
254
251
  rounded.frac= decimal_actual_fraction(&rounded);
255
252
  if (scale < rounded.frac)
256
253
  {
264
261
  return check_result(mask, err2);
265
262
}
266
263
 
267
 
} // namespace type
268
 
 
269
264
 
270
265
/**
271
266
  @brief Convert string for decimal when string can be in some multibyte charset
274
269
  @param  from            string to process
275
270
  @param  length          length of given string
276
271
  @param  charset         charset of given string
 
272
  @param  decimal_value   buffer for result storing
277
273
 
278
274
  @return Error code
279
275
   @retval E_DEC_OK
283
279
   @retval E_DEC_OOM
284
280
*/
285
281
 
286
 
int type::Decimal::store(uint32_t mask, const char *from, uint32_t length, const CHARSET_INFO * charset)
 
282
int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
 
283
                   const CHARSET_INFO * charset, my_decimal *decimal_value)
287
284
{
288
285
  char *end, *from_end;
289
286
  int err;
298
295
    charset= &my_charset_bin;
299
296
  }
300
297
  from_end= end= (char*) from+length;
301
 
  err= string2decimal((char *)from, (decimal_t*) this, &end);
 
298
  err= string2decimal((char *)from, (decimal_t*) decimal_value, &end);
302
299
  if (end != from_end && !err)
303
300
  {
304
301
    /* Give warning if there is something other than end space */
311
308
      }
312
309
    }
313
310
  }
314
 
  check_result_and_overflow(mask, err);
 
311
  check_result_and_overflow(mask, err, decimal_value);
315
312
  return err;
316
313
}
317
314
 
318
 
void type::Decimal::convert(double &result) const
319
 
{
320
 
  decimal2double(static_cast<const decimal_t*>(this), &result);
321
 
}
322
315
 
323
 
type::Decimal *date2_class_decimal(type::Time *ltime, type::Decimal *dec)
 
316
my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec)
324
317
{
325
318
  int64_t date;
326
319
  date = (ltime->year*100L + ltime->month)*100L + ltime->day;
327
 
  if (ltime->time_type > type::DRIZZLE_TIMESTAMP_DATE)
 
320
  if (ltime->time_type > DRIZZLE_TIMESTAMP_DATE)
328
321
    date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
329
 
 
330
 
  if (int2_class_decimal(E_DEC_FATAL_ERROR, date, false, dec))
 
322
  if (int2my_decimal(E_DEC_FATAL_ERROR, date, false, dec))
331
323
    return dec;
332
 
 
333
324
  if (ltime->second_part)
334
325
  {
335
326
    dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
336
327
    dec->frac= 6;
337
328
  }
338
 
 
339
329
  return dec;
340
330
}
341
331
 
342
332
 
343
 
void class_decimal_trim(uint32_t *precision, uint32_t *scale)
 
333
void my_decimal_trim(uint32_t *precision, uint32_t *scale)
344
334
{
345
335
  if (!(*precision) && !(*scale))
346
336
  {
373
363
#define DIG_MASK     100000000
374
364
#define DIG_BASE     1000000000
375
365
#define DIG_MAX      (DIG_BASE-1)
376
 
 
377
 
template<typename T> 
378
 
inline static T round_up(const T &x)
379
 
{
380
 
  return (x+DIG_PER_DEC1-1)/DIG_PER_DEC1;
381
 
}
382
 
 
 
366
#define ROUND_UP(X)  (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
383
367
static const dec1 powers10[DIG_PER_DEC1+1]={
384
368
  1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
385
369
static const int dig2bytes[DIG_PER_DEC1+1]={0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
395
379
                              (d)->buf[(d)->len-1] | 1))
396
380
#endif
397
381
 
398
 
inline static void fix_intg_frac_error(const int len, int &intg1, int &frac1, int &error)
399
 
{
400
 
  if (unlikely(intg1+frac1 > len))
401
 
  {
402
 
    if (unlikely(intg1 > len))
403
 
    {
404
 
      intg1=(len);
405
 
      frac1=0;
406
 
      error=E_DEC_OVERFLOW;
407
 
    }
408
 
    else
409
 
    {
410
 
      frac1=(len)-intg1;
411
 
      error=E_DEC_TRUNCATED;
412
 
    }
413
 
  }
414
 
  else
415
 
    error=E_DEC_OK;
416
 
}
417
 
 
418
 
/* assume carry <= 1 */
419
 
inline static void add(dec1 &to, const dec1 &from1, const dec1& from2, dec1 &carry)
420
 
{
421
 
  dec1 a=from1+from2+carry;
422
 
  assert(carry <= 1);
423
 
  if ((carry= (a >= DIG_BASE))) /* no division here! */
424
 
    a-=DIG_BASE;
425
 
  to=a;
426
 
}
427
 
 
428
 
inline static void add2(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
429
 
{
430
 
  dec2 a=dec2(from1)+from2+carry;
431
 
  if ((carry= (a >= DIG_BASE)))
432
 
    a-=DIG_BASE;
433
 
  if (unlikely(a >= DIG_BASE))
434
 
  {
435
 
    a-=DIG_BASE;
436
 
    carry++;
437
 
  }
438
 
  to=dec1(a);
439
 
}
440
 
 
441
 
/* to=from1-from2 */
442
 
inline static void sub(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
443
 
{
444
 
  dec1 a=from1-from2-carry;
445
 
  if ((carry= (a < 0)))
446
 
    a+=DIG_BASE;
447
 
  to=a;
448
 
}
449
 
 
450
 
/* to=from1-from2 */
451
 
inline static void sub2(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
452
 
{
453
 
  dec1 a=from1-from2-carry;
454
 
  if ((carry= (a < 0)))
455
 
    a+=DIG_BASE;
456
 
  if (unlikely(a < 0))
457
 
  {
458
 
    a+=DIG_BASE;
459
 
    carry++;
460
 
  }
461
 
  to=a;
462
 
}
 
382
#define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error)                   \
 
383
        do                                                              \
 
384
        {                                                               \
 
385
          if (unlikely(intg1+frac1 > (len)))                            \
 
386
          {                                                             \
 
387
            if (unlikely(intg1 > (len)))                                \
 
388
            {                                                           \
 
389
              intg1=(len);                                              \
 
390
              frac1=0;                                                  \
 
391
              error=E_DEC_OVERFLOW;                                     \
 
392
            }                                                           \
 
393
            else                                                        \
 
394
            {                                                           \
 
395
              frac1=(len)-intg1;                                        \
 
396
              error=E_DEC_TRUNCATED;                                    \
 
397
            }                                                           \
 
398
          }                                                             \
 
399
          else                                                          \
 
400
            error=E_DEC_OK;                                             \
 
401
        } while(0)
 
402
 
 
403
#define ADD(to, from1, from2, carry)  /* assume carry <= 1 */           \
 
404
        do                                                              \
 
405
        {                                                               \
 
406
          dec1 a=(from1)+(from2)+(carry);                               \
 
407
          assert((carry) <= 1);                                    \
 
408
          if (((carry)= a >= DIG_BASE)) /* no division here! */         \
 
409
            a-=DIG_BASE;                                                \
 
410
          (to)=a;                                                       \
 
411
        } while(0)
 
412
 
 
413
#define ADD2(to, from1, from2, carry)                                   \
 
414
        do                                                              \
 
415
        {                                                               \
 
416
          dec2 a=((dec2)(from1))+(from2)+(carry);                       \
 
417
          if (((carry)= a >= DIG_BASE))                                 \
 
418
            a-=DIG_BASE;                                                \
 
419
          if (unlikely(a >= DIG_BASE))                                  \
 
420
          {                                                             \
 
421
            a-=DIG_BASE;                                                \
 
422
            carry++;                                                    \
 
423
          }                                                             \
 
424
          (to)=(dec1) a;                                                \
 
425
        } while(0)
 
426
 
 
427
#define SUB(to, from1, from2, carry) /* to=from1-from2 */               \
 
428
        do                                                              \
 
429
        {                                                               \
 
430
          dec1 a=(from1)-(from2)-(carry);                               \
 
431
          if (((carry)= a < 0))                                         \
 
432
            a+=DIG_BASE;                                                \
 
433
          (to)=a;                                                       \
 
434
        } while(0)
 
435
 
 
436
#define SUB2(to, from1, from2, carry) /* to=from1-from2 */              \
 
437
        do                                                              \
 
438
        {                                                               \
 
439
          dec1 a=(from1)-(from2)-(carry);                               \
 
440
          if (((carry)= a < 0))                                         \
 
441
            a+=DIG_BASE;                                                \
 
442
          if (unlikely(a < 0))                                          \
 
443
          {                                                             \
 
444
            a+=DIG_BASE;                                                \
 
445
            carry++;                                                    \
 
446
          }                                                             \
 
447
          (to)=a;                                                       \
 
448
        } while(0)
 
449
 
 
450
/**
 
451
  Swap the contents of two variables.
 
452
 */
 
453
#define swap_variables(TYPE, a, b) \
 
454
  do {                             \
 
455
    TYPE dummy;                    \
 
456
    dummy= a;                      \
 
457
    a= b;                          \
 
458
    b= dummy;                      \
 
459
  } while (0)
 
460
 
 
461
 
463
462
 
464
463
/**
465
464
  @brief  Get maximum value for given precision and scale
528
527
int decimal_actual_fraction(decimal_t *from)
529
528
{
530
529
  int frac= from->frac, i;
531
 
  dec1 *buf0= from->buf + round_up(from->intg) + round_up(frac) - 1;
 
530
  dec1 *buf0= from->buf + ROUND_UP(from->intg) + ROUND_UP(frac) - 1;
532
531
 
533
532
  if (frac == 0)
534
533
    return 0;
633
632
  {
634
633
    char *s1= s + intg_len;
635
634
    fill= frac_len - frac;
636
 
    buf=buf0+round_up(intg);
 
635
    buf=buf0+ROUND_UP(intg);
637
636
    *s1++='.';
638
637
    for (; frac>0; frac-=DIG_PER_DEC1)
639
638
    {
658
657
  if (intg)
659
658
  {
660
659
    s+=intg;
661
 
    for (buf=buf0+round_up(intg); intg>0; intg-=DIG_PER_DEC1)
 
660
    for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
662
661
    {
663
662
      dec1 x=*--buf;
664
663
      for (i=min(intg, DIG_PER_DEC1); i; i--)
688
687
{
689
688
  int start, stop, i;
690
689
  dec1 *buf_beg= from->buf;
691
 
  dec1 *end= from->buf + round_up(from->intg) + round_up(from->frac);
 
690
  dec1 *end= from->buf + ROUND_UP(from->intg) + ROUND_UP(from->frac);
692
691
  dec1 *buf_end= end - 1;
693
692
 
694
693
  /* find non-zero digit from number begining */
754
753
*/
755
754
static void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
756
755
{
757
 
  dec1 *from= dec->buf + round_up(beg + 1) - 1;
758
 
  dec1 *end= dec->buf + round_up(last) - 1;
 
756
  dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
 
757
  dec1 *end= dec->buf + ROUND_UP(last) - 1;
759
758
  int c_shift= DIG_PER_DEC1 - shift;
760
759
  assert(from >= dec->buf);
761
760
  assert(end < dec->buf + dec->len);
782
781
*/
783
782
static void do_mini_right_shift(decimal_t *dec, int shift, int beg, int last)
784
783
{
785
 
  dec1 *from= dec->buf + round_up(last) - 1;
786
 
  dec1 *end= dec->buf + round_up(beg + 1) - 1;
 
784
  dec1 *from= dec->buf + ROUND_UP(last) - 1;
 
785
  dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1;
787
786
  int c_shift= DIG_PER_DEC1 - shift;
788
787
  assert(from < dec->buf + dec->len);
789
788
  assert(end >= dec->buf);
819
818
  /* index of position after last decimal digit */
820
819
  int end;
821
820
  /* index of digit position just after point */
822
 
  int point= round_up(dec->intg) * DIG_PER_DEC1;
 
821
  int point= ROUND_UP(dec->intg) * DIG_PER_DEC1;
823
822
  /* new point position */
824
823
  int new_point= point + shift;
825
824
  /* number of digits in result */
837
836
 
838
837
  if (beg == end)
839
838
  {
840
 
    dec->set_zero();
 
839
    decimal_make_zero(dec);
841
840
    return E_DEC_OK;
842
841
  }
843
842
 
846
845
  digits_frac= end - new_point;
847
846
  set_if_bigger(digits_frac, 0);
848
847
 
849
 
  if ((new_len= round_up(digits_int) + (new_frac_len= round_up(digits_frac))) >
 
848
  if ((new_len= ROUND_UP(digits_int) + (new_frac_len= ROUND_UP(digits_frac))) >
850
849
      dec->len)
851
850
  {
852
851
    int lack= new_len - dec->len;
870
869
        we lost all digits (they will be shifted out of buffer), so we can
871
870
        just return 0
872
871
      */
873
 
      dec->set_zero();
874
 
 
 
872
      decimal_make_zero(dec);
875
873
      return E_DEC_TRUNCATED;
876
874
    }
877
875
  }
907
905
    if (do_left)
908
906
    {
909
907
      do_mini_left_shift(dec, l_mini_shift, beg, end);
910
 
      mini_shift= (-l_mini_shift);
 
908
      mini_shift=- l_mini_shift;
911
909
    }
912
910
    else
913
911
    {
940
938
    {
941
939
      /* move left */
942
940
      d_shift= new_front / DIG_PER_DEC1;
943
 
      to= dec->buf + (round_up(beg + 1) - 1 - d_shift);
944
 
      barier= dec->buf + (round_up(end) - 1 - d_shift);
 
941
      to= dec->buf + (ROUND_UP(beg + 1) - 1 - d_shift);
 
942
      barier= dec->buf + (ROUND_UP(end) - 1 - d_shift);
945
943
      assert(to >= dec->buf);
946
944
      assert(barier + d_shift < dec->buf + dec->len);
947
945
      for(; to <= barier; to++)
954
952
    {
955
953
      /* move right */
956
954
      d_shift= (1 - new_front) / DIG_PER_DEC1;
957
 
      to= dec->buf + round_up(end) - 1 + d_shift;
958
 
      barier= dec->buf + round_up(beg + 1) - 1 + d_shift;
 
955
      to= dec->buf + ROUND_UP(end) - 1 + d_shift;
 
956
      barier= dec->buf + ROUND_UP(beg + 1) - 1 + d_shift;
959
957
      assert(to < dec->buf + dec->len);
960
958
      assert(barier - d_shift >= dec->buf);
961
959
      for(; to >= barier; to--)
974
972
 
975
973
    Only one of following 'for' loops will work becouse beg <= end
976
974
  */
977
 
  beg= round_up(beg + 1) - 1;
978
 
  end= round_up(end) - 1;
 
975
  beg= ROUND_UP(beg + 1) - 1;
 
976
  end= ROUND_UP(end) - 1;
979
977
  assert(new_point >= 0);
980
978
 
981
979
  /* We don't want negative new_point below */
982
980
  if (new_point != 0)
983
 
    new_point= round_up(new_point) - 1;
 
981
    new_point= ROUND_UP(new_point) - 1;
984
982
 
985
983
  if (new_point > end)
986
984
  {
1075
1073
      error=E_DEC_OVERFLOW;
1076
1074
      intg=to->intg;
1077
1075
    }
1078
 
    intg1=round_up(intg);
1079
 
    frac1=round_up(frac);
 
1076
    intg1=ROUND_UP(intg);
 
1077
    frac1=ROUND_UP(frac);
1080
1078
    if (intg1+frac1 > to->len)
1081
1079
    {
1082
1080
      error= E_DEC_OOM;
1085
1083
  }
1086
1084
  else
1087
1085
  {
1088
 
    intg1=round_up(intg);
1089
 
    frac1=round_up(frac);
1090
 
    fix_intg_frac_error(to->len, intg1, frac1, error);
 
1086
    intg1=ROUND_UP(intg);
 
1087
    frac1=ROUND_UP(frac);
 
1088
    FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
1091
1089
    if (unlikely(error))
1092
1090
    {
1093
1091
      frac=frac1*DIG_PER_DEC1;
1163
1161
  return error;
1164
1162
 
1165
1163
fatal_error:
1166
 
  to->set_zero();
 
1164
  decimal_make_zero(to);
1167
1165
  return error;
1168
1166
}
1169
1167
 
1551
1549
  d_copy[0]^= 0x80;
1552
1550
  from= d_copy;
1553
1551
 
1554
 
  fix_intg_frac_error(to->len, intg1, frac1, error);
 
1552
  FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
1555
1553
  if (unlikely(error))
1556
1554
  {
1557
1555
    if (intg1 < intg0+(intg0x>0))
1632
1630
  return error;
1633
1631
 
1634
1632
err:
1635
 
  to->set_zero();
 
1633
  decimal_make_zero(((decimal_t*) to));
1636
1634
  return(E_DEC_BAD_NUM);
1637
1635
}
1638
1636
 
1671
1669
decimal_round(const decimal_t *from, decimal_t *to, int scale,
1672
1670
              decimal_round_mode mode)
1673
1671
{
1674
 
  int frac0=scale>0 ? round_up(scale) : scale/DIG_PER_DEC1,
1675
 
      frac1=round_up(from->frac), round_digit= 0,
1676
 
      intg0=round_up(from->intg), error=E_DEC_OK, len=to->len,
1677
 
      intg1=round_up(from->intg +
 
1672
  int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
 
1673
      frac1=ROUND_UP(from->frac), round_digit= 0,
 
1674
      intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len,
 
1675
      intg1=ROUND_UP(from->intg +
1678
1676
                     (((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX)));
1679
1677
  dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
1680
1678
  int first_dig;
1699
1697
 
1700
1698
  if (scale+from->intg < 0)
1701
1699
  {
1702
 
    to->set_zero();
 
1700
    decimal_make_zero(to);
1703
1701
    return E_DEC_OK;
1704
1702
  }
1705
1703
 
1770
1768
    }
1771
1769
    else if (frac0+intg0==0)
1772
1770
    {
1773
 
      to->set_zero();
 
1771
      decimal_make_zero(to);
1774
1772
      return E_DEC_OK;
1775
1773
    }
1776
1774
  }
1809
1807
    carry=1;
1810
1808
    *buf1-=DIG_BASE;
1811
1809
    while (carry && --buf1 >= to->buf)
1812
 
      add(*buf1, *buf1, 0, carry);
 
1810
      ADD(*buf1, *buf1, 0, carry);
1813
1811
    if (unlikely(carry))
1814
1812
    {
1815
1813
      /* shifting the number to create space for new digit */
1862
1860
 
1863
1861
static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1864
1862
{
1865
 
  int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
1866
 
      frac1=round_up(from1->frac), frac2=round_up(from2->frac),
 
1863
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
 
1864
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1867
1865
      frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
1868
1866
  dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
1869
1867
 
1879
1877
    to->buf[0]=0; /* safety */
1880
1878
  }
1881
1879
 
1882
 
  fix_intg_frac_error(to->len, intg0, frac0, error);
 
1880
  FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
1883
1881
  if (unlikely(error == E_DEC_OVERFLOW))
1884
1882
  {
1885
1883
    max_decimal(to->len * DIG_PER_DEC1, 0, to);
1922
1920
  carry=0;
1923
1921
  while (buf1 > stop2)
1924
1922
  {
1925
 
    add(*--buf0, *--buf1, *--buf2, carry);
 
1923
    ADD(*--buf0, *--buf1, *--buf2, carry);
1926
1924
  }
1927
1925
 
1928
1926
  /* part 3 - cmin(intg) ... cmax(intg) */
1930
1928
                        ((stop=from2->buf)+intg2-intg1) ;
1931
1929
  while (buf1 > stop)
1932
1930
  {
1933
 
    add(*--buf0, *--buf1, 0, carry);
 
1931
    ADD(*--buf0, *--buf1, 0, carry);
1934
1932
  }
1935
1933
 
1936
1934
  if (unlikely(carry))
1944
1942
   if to==0, return -1/0/+1 - the result of the comparison */
1945
1943
static int do_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1946
1944
{
1947
 
  int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
1948
 
      frac1=round_up(from1->frac), frac2=round_up(from2->frac);
 
1945
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
 
1946
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
1949
1947
  int frac0=max(frac1, frac2), error;
1950
1948
  dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
1951
1949
 
1995
1993
      {
1996
1994
        if (to == 0) /* decimal_cmp() */
1997
1995
          return 0;
1998
 
 
1999
 
        to->set_zero();
2000
 
 
 
1996
        decimal_make_zero(to);
2001
1997
        return E_DEC_OK;
2002
1998
      }
2003
1999
    }
2013
2009
  /* ensure that always from1 > from2 (and intg1 >= intg2) */
2014
2010
  if (carry)
2015
2011
  {
2016
 
    swap(from1, from2);
2017
 
    swap(start1, start2);
2018
 
    swap(intg1, intg2);
2019
 
    swap(frac1, frac2);
 
2012
    swap_variables(const decimal_t *,from1, from2);
 
2013
    swap_variables(dec1 *,start1, start2);
 
2014
    swap_variables(int,intg1,intg2);
 
2015
    swap_variables(int,frac1,frac2);
2020
2016
    to->sign= 1 - to->sign;
2021
2017
  }
2022
2018
 
2023
 
  fix_intg_frac_error(to->len, intg1, frac0, error);
 
2019
  FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
2024
2020
  buf0=to->buf+intg1+frac0;
2025
2021
 
2026
2022
  to->frac=max(from1->frac, from2->frac);
2054
2050
      *--buf0=0;
2055
2051
    while (buf2 > stop2)
2056
2052
    {
2057
 
      sub(*--buf0, 0, *--buf2, carry);
 
2053
      SUB(*--buf0, 0, *--buf2, carry);
2058
2054
    }
2059
2055
  }
2060
2056
 
2061
2057
  /* part 2 - cmin(frac) ... intg2 */
2062
2058
  while (buf2 > start2)
2063
2059
  {
2064
 
    sub(*--buf0, *--buf1, *--buf2, carry);
 
2060
    SUB(*--buf0, *--buf1, *--buf2, carry);
2065
2061
  }
2066
2062
 
2067
2063
  /* part 3 - intg2 ... intg1 */
2068
2064
  while (carry && buf1 > start1)
2069
2065
  {
2070
 
    sub(*--buf0, *--buf1, 0, carry);
 
2066
    SUB(*--buf0, *--buf1, 0, carry);
2071
2067
  }
2072
2068
 
2073
2069
  while (buf1 > start1)
2108
2104
  return from1->sign > from2->sign ? -1 : 1;
2109
2105
}
2110
2106
 
2111
 
int decimal_t::isZero() const
 
2107
int decimal_is_zero(const decimal_t *from)
2112
2108
{
2113
 
  dec1 *buf1= buf,
2114
 
       *end= buf1 +round_up(intg) +round_up(frac);
2115
 
 
 
2109
  dec1 *buf1=from->buf,
 
2110
       *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2116
2111
  while (buf1 < end)
2117
 
  {
2118
2112
    if (*buf1++)
2119
 
    {
2120
2113
      return 0;
2121
 
    }
2122
 
  }
2123
 
 
2124
2114
  return 1;
2125
2115
}
2126
2116
 
2146
2136
*/
2147
2137
int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2148
2138
{
2149
 
  int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
2150
 
      frac1=round_up(from1->frac), frac2=round_up(from2->frac),
2151
 
      intg0=round_up(from1->intg+from2->intg),
 
2139
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
 
2140
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
 
2141
      intg0=ROUND_UP(from1->intg+from2->intg),
2152
2142
      frac0=frac1+frac2, error, i, j, d_to_move;
2153
2143
  dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
2154
2144
       *start2, *stop2, *stop1, *start0, carry;
2157
2147
 
2158
2148
  i=intg0;
2159
2149
  j=frac0;
2160
 
  fix_intg_frac_error(to->len, intg0, frac0, error);
 
2150
  FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2161
2151
  to->sign=from1->sign != from2->sign;
2162
2152
  to->frac=from1->frac+from2->frac;
2163
2153
  to->intg=intg0*DIG_PER_DEC1;
2198
2188
      dec2 p= ((dec2)*buf1) * ((dec2)*buf2);
2199
2189
      hi=(dec1)(p/DIG_BASE);
2200
2190
      lo=(dec1)(p-((dec2)hi)*DIG_BASE);
2201
 
      add2(*buf0, *buf0, lo, carry);
 
2191
      ADD2(*buf0, *buf0, lo, carry);
2202
2192
      carry+=hi;
2203
2193
    }
2204
2194
    if (carry)
2205
2195
    {
2206
2196
      if (buf0 < to->buf)
2207
2197
        return E_DEC_OVERFLOW;
2208
 
      add2(*buf0, *buf0, 0, carry);
 
2198
      ADD2(*buf0, *buf0, 0, carry);
2209
2199
    }
2210
2200
    for (buf0--; carry; buf0--)
2211
2201
    {
2212
2202
      if (buf0 < to->buf)
2213
2203
        return E_DEC_OVERFLOW;
2214
 
      add(*buf0, *buf0, 0, carry);
 
2204
      ADD(*buf0, *buf0, 0, carry);
2215
2205
    }
2216
2206
  }
2217
2207
 
2228
2218
      if (++buf == end)
2229
2219
      {
2230
2220
        /* We got decimal zero */
2231
 
        to->set_zero();
 
2221
        decimal_make_zero(to);
2232
2222
        break;
2233
2223
      }
2234
2224
    }
2235
2225
  }
2236
2226
  buf1= to->buf;
2237
 
  d_to_move= intg0 + round_up(to->frac);
 
2227
  d_to_move= intg0 + ROUND_UP(to->frac);
2238
2228
  while (!*buf1 && (to->intg > DIG_PER_DEC1))
2239
2229
  {
2240
2230
    buf1++;
2264
2254
static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2265
2255
                       decimal_t *to, decimal_t *mod, int scale_incr)
2266
2256
{
2267
 
  int frac1=round_up(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2268
 
      frac2=round_up(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
 
2257
  int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
 
2258
      frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2269
2259
      error= 0, i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2270
2260
  dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2271
2261
       *start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
2298
2288
  }
2299
2289
  if (prec1 <= 0)
2300
2290
  { /* short-circuit everything: from1 == 0 */
2301
 
    to->set_zero();
 
2291
    decimal_make_zero(to);
2302
2292
    return E_DEC_OK;
2303
2293
  }
2304
2294
  for (i=(prec1-1) % DIG_PER_DEC1; *buf1 < powers10[i--]; prec1--) ;
2315
2305
    intg0=0;
2316
2306
  }
2317
2307
  else
2318
 
    intg0=round_up(dintg);
 
2308
    intg0=ROUND_UP(dintg);
2319
2309
  if (mod)
2320
2310
  {
2321
2311
    /* we're calculating N1 % N2.
2334
2324
      N2 is in the buf2, has prec2 digits. Scales are frac1 and
2335
2325
      frac2 accordingly.
2336
2326
      Thus, the result will have
2337
 
         frac = round_up(frac1+frac2+scale_incr)
 
2327
         frac = ROUND_UP(frac1+frac2+scale_incr)
2338
2328
      and
2339
2329
         intg = (prec1-frac1) - (prec2-frac2) + 1
2340
2330
         prec = intg+frac
2341
2331
    */
2342
 
    frac0=round_up(frac1+frac2+scale_incr);
2343
 
    fix_intg_frac_error(to->len, intg0, frac0, error);
 
2332
    frac0=ROUND_UP(frac1+frac2+scale_incr);
 
2333
    FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2344
2334
    to->sign=from1->sign != from2->sign;
2345
2335
    to->intg=intg0*DIG_PER_DEC1;
2346
2336
    to->frac=frac0*DIG_PER_DEC1;
2351
2341
    while (dintg++ < 0)
2352
2342
      *buf0++=0;
2353
2343
 
2354
 
  len1=(i=round_up(prec1))+round_up(2*frac2+scale_incr+1) + 1;
 
2344
  len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1;
2355
2345
  set_if_bigger(len1, 3);
2356
2346
  if (!(tmp1=(dec1 *)alloca(len1*sizeof(dec1))))
2357
2347
    return E_DEC_OOM;
2361
2351
  start1=tmp1;
2362
2352
  stop1=start1+len1;
2363
2353
  start2=buf2;
2364
 
  stop2=buf2+round_up(prec2)-1;
 
2354
  stop2=buf2+ROUND_UP(prec2)-1;
2365
2355
 
2366
2356
  /* removing end zeroes */
2367
2357
  while (*stop2 == 0 && stop2 >= start2)
2420
2410
        x=guess * (*--buf2);
2421
2411
        hi=(dec1)(x/DIG_BASE);
2422
2412
        lo=(dec1)(x-((dec2)hi)*DIG_BASE);
2423
 
        sub2(*buf1, *buf1, lo, carry);
 
2413
        SUB2(*buf1, *buf1, lo, carry);
2424
2414
        carry+=hi;
2425
2415
      }
2426
2416
      carry= dcarry < carry;
2434
2424
        buf1=start1+len2;
2435
2425
        for (carry=0; buf2 > start2; buf1--)
2436
2426
        {
2437
 
          add(*buf1, *buf1, *--buf2, carry);
 
2427
          ADD(*buf1, *buf1, *--buf2, carry);
2438
2428
        }
2439
2429
      }
2440
2430
    }
2453
2443
    if (dcarry)
2454
2444
      *--start1=dcarry;
2455
2445
    buf0=to->buf;
2456
 
    intg0=(int) (round_up(prec1-frac1)-(start1-tmp1));
2457
 
    frac0=round_up(to->frac);
 
2446
    intg0=(int) (ROUND_UP(prec1-frac1)-(start1-tmp1));
 
2447
    frac0=ROUND_UP(to->frac);
2458
2448
    error=E_DEC_OK;
2459
2449
    if (unlikely(frac0==0 && intg0==0))
2460
2450
    {
2461
 
      to->set_zero();
 
2451
      decimal_make_zero(to);
2462
2452
      goto done;
2463
2453
    }
2464
2454
    if (intg0<=0)
2465
2455
    {
2466
2456
      if (unlikely(-intg0 >= to->len))
2467
2457
      {
2468
 
        to->set_zero();
 
2458
        decimal_make_zero(to);
2469
2459
        error=E_DEC_TRUNCATED;
2470
2460
        goto done;
2471
2461
      }
2484
2474
        error=E_DEC_OVERFLOW;
2485
2475
        goto done;
2486
2476
      }
2487
 
      assert(intg0 <= round_up(from2->intg));
 
2477
      assert(intg0 <= ROUND_UP(from2->intg));
2488
2478
      stop1=start1+frac0+intg0;
2489
2479
      to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
2490
2480
    }
2552
2542
  return do_div_mod(from1, from2, 0, to, 0);
2553
2543
}
2554
2544
 
2555
 
std::ostream& operator<<(std::ostream& output, const type::Decimal &dec)
2556
 
{
2557
 
  drizzled::String str;
2558
 
 
2559
 
  class_decimal2string(&dec, 0, &str);
2560
 
 
2561
 
  output << "type::Decimal:(";
2562
 
  output <<  str.c_ptr();
2563
 
  output << ")";
2564
 
 
2565
 
  return output;  // for multiple << operators.
2566
 
}
2567
 
 
2568
2545
} /* namespace drizzled */
2569
2546
 
2570
2547
#ifdef MAIN
2577
2554
{
2578
2555
  int i;
2579
2556
  printf("/* intg=%d, frac=%d, sign=%d, buf[]={", d->intg, d->frac, d->sign);
2580
 
  for (i=0; i < round_up(d->frac)+round_up(d->intg)-1; i++)
 
2557
  for (i=0; i < ROUND_UP(d->frac)+ROUND_UP(d->intg)-1; i++)
2581
2558
    printf("%09d, ", d->buf[i]);
2582
2559
  printf("%09d} */ ", d->buf[i]);
2583
2560
}
3298
3275
 
3299
3276
  return 0;
3300
3277
}
3301
 
 
3302
3278
#endif