~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to strings/decimal.c

  • Committer: Jay Pipes
  • Date: 2008-07-17 18:48:58 UTC
  • mto: This revision was merged to the branch mainline in revision 182.
  • Revision ID: jay@mysql.com-20080717184858-2mbouxl8xi41gcge
Removed DBUG from CSV and Blackhole storage engines

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 */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
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
 
 */
 
16
#line 18 "decimal.c"
25
17
 
26
18
/*
27
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
=======================================================================
28
24
  Quoting the standard
29
25
  (SQL:2003, Part 2 Foundations, aka ISO/IEC 9075-2:2003)
30
26
 
103
99
      implementation-defined.
104
100
*/
105
101
 
106
 
#include <config.h>
107
 
 
108
 
#include <drizzled/definitions.h>
109
 
#include <drizzled/internal/m_string.h>
110
 
#include <drizzled/charset_info.h>
111
 
#include <drizzled/type/decimal.h>
112
 
 
113
 
#include <plugin/myisam/myisampack.h>
114
 
#include <drizzled/util/test.h>
115
 
 
116
 
#ifdef HAVE_ALLOCA_H
117
 
#include <alloca.h>
118
 
#endif
119
 
 
120
 
#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
 
 
127
 
using namespace std;
128
 
 
129
 
namespace drizzled
130
 
{
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 type::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 class_decimal2string(const type::Decimal *d,
198
 
                         uint32_t fixed_dec, String *str)
199
 
{
200
 
  uint32_t mask= E_DEC_FATAL_ERROR;
201
 
 
202
 
  /*
203
 
    Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a
204
 
    holds true iff the type is also ZEROFILL, which in turn implies
205
 
    UNSIGNED. Hence the buffer for a ZEROFILLed value is the length
206
 
    the user requested, plus one for a possible decimal point, plus
207
 
    one if the user only wanted decimal places, but we force a leading
208
 
    zero on them. Because the type is implicitly UNSIGNED, we do not
209
 
    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
211
 
    instead to calculate the required size of the buffer.
212
 
  */
213
 
  int length= (int)(0
214
 
                    ? (uint32_t)(((0 == fixed_dec) ? 1 : 0) + 1)
215
 
                    : (uint32_t)d->string_length());
216
 
  int result;
217
 
  if (str->alloc(length))
218
 
    return check_result(mask, E_DEC_OOM);
219
 
 
220
 
  result= decimal2string((decimal_t*) d, (char*) str->ptr(),
221
 
                         &length, (int)0, fixed_dec,
222
 
                         '0');
223
 
  str->length(length);
224
 
  return check_result(mask, result);
225
 
}
226
 
 
227
 
 
228
 
/**
229
 
  @brief  Convert from decimal to binary representation
230
 
 
231
 
  @param[in]   mask        error processing mask
232
 
  @param[in]   d           number for conversion
233
 
  @param[out]  bin         pointer to buffer where to write result
234
 
  @param[in]   prec        overall number of decimal digits
235
 
  @param[in]   scale       number of decimal digits after decimal point
236
 
 
237
 
  @note
238
 
    Before conversion we round number if it need but produce truncation
239
 
    error in this case
240
 
 
241
 
  @return error code
242
 
   @retval E_DEC_OK
243
 
   @retval E_DEC_TRUNCATED
244
 
   @retval E_DEC_OVERFLOW
245
 
*/
246
 
 
247
 
namespace type {
248
 
 
249
 
int Decimal::val_binary(uint32_t mask, unsigned char *bin, int prec, int scale) const
250
 
{
251
 
  int err1= E_DEC_OK, err2;
252
 
  type::Decimal rounded;
253
 
  class_decimal2decimal(this, &rounded);
254
 
  rounded.frac= decimal_actual_fraction(&rounded);
255
 
  if (scale < rounded.frac)
256
 
  {
257
 
    err1= E_DEC_TRUNCATED;
258
 
    /* decimal_round can return only E_DEC_TRUNCATED */
259
 
    decimal_round(&rounded, &rounded, scale, HALF_UP);
260
 
  }
261
 
  err2= decimal2bin(&rounded, bin, prec, scale);
262
 
  if (!err2)
263
 
    err2= err1;
264
 
  return check_result(mask, err2);
265
 
}
266
 
 
267
 
} // namespace type
268
 
 
269
 
 
270
 
/**
271
 
  @brief Convert string for decimal when string can be in some multibyte charset
272
 
 
273
 
  @param  mask            error processing mask
274
 
  @param  from            string to process
275
 
  @param  length          length of given string
276
 
  @param  charset         charset of given string
277
 
 
278
 
  @return Error code
279
 
   @retval E_DEC_OK
280
 
   @retval E_DEC_TRUNCATED
281
 
   @retval E_DEC_OVERFLOW
282
 
   @retval E_DEC_BAD_NUM
283
 
   @retval E_DEC_OOM
284
 
*/
285
 
 
286
 
int type::Decimal::store(uint32_t mask, const char *from, uint32_t length, const CHARSET_INFO * charset)
287
 
{
288
 
  char *end, *from_end;
289
 
  int err;
290
 
  char buff[STRING_BUFFER_USUAL_SIZE];
291
 
  String tmp(buff, sizeof(buff), &my_charset_bin);
292
 
  if (charset->mbminlen > 1)
293
 
  {
294
 
    size_t dummy_errors;
295
 
    tmp.copy(from, length, charset, &my_charset_utf8_general_ci, &dummy_errors);
296
 
    from= tmp.ptr();
297
 
    length=  tmp.length();
298
 
    charset= &my_charset_bin;
299
 
  }
300
 
  from_end= end= (char*) from+length;
301
 
  err= string2decimal((char *)from, (decimal_t*) this, &end);
302
 
  if (end != from_end && !err)
303
 
  {
304
 
    /* Give warning if there is something other than end space */
305
 
    for ( ; end < from_end; end++)
306
 
    {
307
 
      if (!my_isspace(&my_charset_utf8_general_ci, *end))
308
 
      {
309
 
        err= E_DEC_TRUNCATED;
310
 
        break;
311
 
      }
312
 
    }
313
 
  }
314
 
  check_result_and_overflow(mask, err);
315
 
  return err;
316
 
}
317
 
 
318
 
void type::Decimal::convert(double &result) const
319
 
{
320
 
  decimal2double(static_cast<const decimal_t*>(this), &result);
321
 
}
322
 
 
323
 
type::Decimal *date2_class_decimal(type::Time *ltime, type::Decimal *dec)
324
 
{
325
 
  int64_t date;
326
 
  date = (ltime->year*100L + ltime->month)*100L + ltime->day;
327
 
  if (ltime->time_type > type::DRIZZLE_TIMESTAMP_DATE)
328
 
    date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
329
 
 
330
 
  if (int2_class_decimal(E_DEC_FATAL_ERROR, date, false, dec))
331
 
    return dec;
332
 
 
333
 
  if (ltime->second_part)
334
 
  {
335
 
    dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
336
 
    dec->frac= 6;
337
 
  }
338
 
 
339
 
  return dec;
340
 
}
341
 
 
342
 
 
343
 
void class_decimal_trim(uint32_t *precision, uint32_t *scale)
344
 
{
345
 
  if (!(*precision) && !(*scale))
346
 
  {
347
 
    *precision= 10;
348
 
    *scale= 0;
349
 
    return;
350
 
  }
351
 
}
352
 
 
 
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>
353
108
 
354
109
/*
355
110
  Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
373
128
#define DIG_MASK     100000000
374
129
#define DIG_BASE     1000000000
375
130
#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
 
 
 
131
#define DIG_BASE2    ((dec2)DIG_BASE * (dec2)DIG_BASE)
 
132
#define ROUND_UP(X)  (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
383
133
static const dec1 powers10[DIG_PER_DEC1+1]={
384
134
  1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
385
135
static const int dig2bytes[DIG_PER_DEC1+1]={0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
388
138
  999900000, 999990000, 999999000,
389
139
  999999900, 999999990 };
390
140
 
391
 
#ifdef HAVE_VALGRIND
392
 
#define sanity(d) assert((d)->len > 0)
 
141
#ifdef HAVE_purify
 
142
#define sanity(d) DBUG_ASSERT((d)->len > 0)
393
143
#else
394
 
#define sanity(d) assert((d)->len >0 && ((d)->buf[0] | \
 
144
#define sanity(d) DBUG_ASSERT((d)->len >0 && ((d)->buf[0] | \
395
145
                              (d)->buf[(d)->len-1] | 1))
396
146
#endif
397
147
 
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
 
}
463
 
 
464
 
/**
465
 
  @brief  Get maximum value for given precision and scale
466
 
 
467
 
  @param  precision/scale  see decimal_bin_size() below
468
 
  @param  to              decimal where where the result will be stored
 
148
#define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error)                   \
 
149
        do                                                              \
 
150
        {                                                               \
 
151
          if (unlikely(intg1+frac1 > (len)))                            \
 
152
          {                                                             \
 
153
            if (unlikely(intg1 > (len)))                                \
 
154
            {                                                           \
 
155
              intg1=(len);                                              \
 
156
              frac1=0;                                                  \
 
157
              error=E_DEC_OVERFLOW;                                     \
 
158
            }                                                           \
 
159
            else                                                        \
 
160
            {                                                           \
 
161
              frac1=(len)-intg1;                                        \
 
162
              error=E_DEC_TRUNCATED;                                    \
 
163
            }                                                           \
 
164
          }                                                             \
 
165
          else                                                          \
 
166
            error=E_DEC_OK;                                             \
 
167
        } while(0)
 
168
 
 
169
#define ADD(to, from1, from2, carry)  /* assume carry <= 1 */           \
 
170
        do                                                              \
 
171
        {                                                               \
 
172
          dec1 a=(from1)+(from2)+(carry);                               \
 
173
          DBUG_ASSERT((carry) <= 1);                                    \
 
174
          if (((carry)= a >= DIG_BASE)) /* no division here! */         \
 
175
            a-=DIG_BASE;                                                \
 
176
          (to)=a;                                                       \
 
177
        } while(0)
 
178
 
 
179
#define ADD2(to, from1, from2, carry)                                   \
 
180
        do                                                              \
 
181
        {                                                               \
 
182
          dec2 a=((dec2)(from1))+(from2)+(carry);                       \
 
183
          if (((carry)= a >= DIG_BASE))                                 \
 
184
            a-=DIG_BASE;                                                \
 
185
          if (unlikely(a >= DIG_BASE))                                  \
 
186
          {                                                             \
 
187
            a-=DIG_BASE;                                                \
 
188
            carry++;                                                    \
 
189
          }                                                             \
 
190
          (to)=(dec1) a;                                                \
 
191
        } while(0)
 
192
 
 
193
#define SUB(to, from1, from2, carry) /* to=from1-from2 */               \
 
194
        do                                                              \
 
195
        {                                                               \
 
196
          dec1 a=(from1)-(from2)-(carry);                               \
 
197
          if (((carry)= a < 0))                                         \
 
198
            a+=DIG_BASE;                                                \
 
199
          (to)=a;                                                       \
 
200
        } while(0)
 
201
 
 
202
#define SUB2(to, from1, from2, carry) /* to=from1-from2 */              \
 
203
        do                                                              \
 
204
        {                                                               \
 
205
          dec1 a=(from1)-(from2)-(carry);                               \
 
206
          if (((carry)= a < 0))                                         \
 
207
            a+=DIG_BASE;                                                \
 
208
          if (unlikely(a < 0))                                          \
 
209
          {                                                             \
 
210
            a+=DIG_BASE;                                                \
 
211
            carry++;                                                    \
 
212
          }                                                             \
 
213
          (to)=a;                                                       \
 
214
        } while(0)
 
215
 
 
216
/*
 
217
  Get maximum value for given precision and scale
 
218
 
 
219
  SYNOPSIS
 
220
    max_decimal()
 
221
    precision/scale - see decimal_bin_size() below
 
222
    to              - decimal where where the result will be stored
469
223
                      to->buf and to->len must be set.
470
224
*/
471
225
 
473
227
{
474
228
  int intpart;
475
229
  dec1 *buf= to->buf;
476
 
  assert(precision && precision >= frac);
 
230
  DBUG_ASSERT(precision && precision >= frac);
477
231
 
478
232
  to->sign= 0;
479
233
  if ((intpart= to->intg= (precision - frac)))
480
234
  {
481
 
    const int firstdigits= intpart % DIG_PER_DEC1;
 
235
    int firstdigits= intpart % DIG_PER_DEC1;
482
236
    if (firstdigits)
483
237
      *buf++= powers10[firstdigits] - 1; /* get 9 99 999 ... */
484
238
    for(intpart/= DIG_PER_DEC1; intpart; intpart--)
487
241
 
488
242
  if ((to->frac= frac))
489
243
  {
490
 
    const int lastdigits= frac % DIG_PER_DEC1;
 
244
    int lastdigits= frac % DIG_PER_DEC1;
491
245
    for(frac/= DIG_PER_DEC1; frac; frac--)
492
246
      *buf++= DIG_MAX;
493
247
    if (lastdigits)
496
250
}
497
251
 
498
252
 
499
 
static dec1 *remove_leading_zeroes(const decimal_t *from, int *intg_result)
 
253
static dec1 *remove_leading_zeroes(decimal_t *from, int *intg_result)
500
254
{
501
255
  int intg= from->intg, i;
502
256
  dec1 *buf0= from->buf;
510
264
  if (intg > 0)
511
265
  {
512
266
    for (i= (intg - 1) % DIG_PER_DEC1; *buf0 < powers10[i--]; intg--) ;
513
 
    assert(intg > 0);
 
267
    DBUG_ASSERT(intg > 0);
514
268
  }
515
269
  else
516
270
    intg=0;
519
273
}
520
274
 
521
275
 
522
 
/**
523
 
 @brief Count actual length of fraction part (without ending zeroes)
 
276
/*
 
277
  Count actual length of fraction part (without ending zeroes)
524
278
 
525
 
 @param from    number for processing
 
279
  SYNOPSIS
 
280
    decimal_actual_fraction()
 
281
    from    number for processing
526
282
*/
527
283
 
528
284
int decimal_actual_fraction(decimal_t *from)
529
285
{
530
286
  int frac= from->frac, i;
531
 
  dec1 *buf0= from->buf + round_up(from->intg) + round_up(frac) - 1;
 
287
  dec1 *buf0= from->buf + ROUND_UP(from->intg) + ROUND_UP(frac) - 1;
532
288
 
533
289
  if (frac == 0)
534
290
    return 0;
548
304
}
549
305
 
550
306
 
551
 
/**
552
 
 @brief  Convert decimal to its printable string representation
 
307
/*
 
308
  Convert decimal to its printable string representation
553
309
 
554
 
 @param  from       value to convert
555
 
 @param  to         points to buffer where string representation
556
 
                    should be stored
557
 
 @param  to_len     in:  size of to buffer
558
 
                    out: length of the actually written string
559
 
 @param  fixed_precision 0 if representation can be variable length and
 
310
  SYNOPSIS
 
311
    decimal2string()
 
312
      from            - value to convert
 
313
      to              - points to buffer where string representation
 
314
                        should be stored
 
315
      *to_len         - in:  size of to buffer
 
316
                        out: length of the actually written string
 
317
      fixed_precision - 0 if representation can be variable length and
560
318
                        fixed_decimals will not be checked in this case.
561
319
                        Put number as with fixed point position with this
562
320
                        number of digits (sign counted and decimal point is
563
321
                        counted)
564
 
 @param  fixed_decimals  number digits after point.
565
 
 @param  filler          character to fill gaps in case of fixed_precision > 0
 
322
      fixed_decimals  - number digits after point.
 
323
      filler          - character to fill gaps in case of fixed_precision > 0
566
324
 
567
 
 @return error code
568
 
   @retval E_DEC_OK
569
 
   @retval E_DEC_TRUNCATED
570
 
   @retval E_DEC_OVERFLOW
 
325
  RETURN VALUE
 
326
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
571
327
*/
572
 
int decimal2string(const decimal_t *from, char *to, int *to_len,
 
328
 
 
329
int decimal2string(decimal_t *from, char *to, int *to_len,
573
330
                   int fixed_precision, int fixed_decimals,
574
331
                   char filler)
575
332
{
581
338
  char *s=to;
582
339
  dec1 *buf, *buf0=from->buf, tmp;
583
340
 
584
 
  assert(*to_len >= 2+from->sign);
 
341
  DBUG_ASSERT(*to_len >= 2+from->sign);
585
342
 
586
343
  /* removing leading zeroes */
587
344
  buf0= remove_leading_zeroes(from, &intg);
633
390
  {
634
391
    char *s1= s + intg_len;
635
392
    fill= frac_len - frac;
636
 
    buf=buf0+round_up(intg);
 
393
    buf=buf0+ROUND_UP(intg);
637
394
    *s1++='.';
638
395
    for (; frac>0; frac-=DIG_PER_DEC1)
639
396
    {
641
398
      for (i=min(frac, DIG_PER_DEC1); i; i--)
642
399
      {
643
400
        dec1 y=x/DIG_MASK;
644
 
        *s1++='0'+(unsigned char)y;
 
401
        *s1++='0'+(uchar)y;
645
402
        x-=y*DIG_MASK;
646
403
        x*=10;
647
404
      }
658
415
  if (intg)
659
416
  {
660
417
    s+=intg;
661
 
    for (buf=buf0+round_up(intg); intg>0; intg-=DIG_PER_DEC1)
 
418
    for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
662
419
    {
663
420
      dec1 x=*--buf;
664
421
      for (i=min(intg, DIG_PER_DEC1); i; i--)
665
422
      {
666
423
        dec1 y=x/10;
667
 
        *--s='0'+(unsigned char)(x-y*10);
 
424
        *--s='0'+(uchar)(x-y*10);
668
425
        x=y;
669
426
      }
670
427
    }
675
432
}
676
433
 
677
434
 
678
 
/**
679
 
 @brief  Return bounds of decimal digits in the number
 
435
/*
 
436
  Return bounds of decimal digits in the number
680
437
 
681
 
 @param  from  decimal number for processing
682
 
 @param  start_result  index (from 0 ) of first decimal digits will
683
 
                       be written by this address
684
 
 @param  end_result   index of position just after last decimal digit
 
438
  SYNOPSIS
 
439
    digits_bounds()
 
440
      from         - decimal number for processing
 
441
      start_result - index (from 0 ) of first decimal digits will
 
442
                     be written by this address
 
443
      end_result   - index of position just after last decimal digit
685
444
                     be written by this address
686
445
*/
 
446
 
687
447
static void digits_bounds(decimal_t *from, int *start_result, int *end_result)
688
448
{
689
449
  int start, stop, i;
690
450
  dec1 *buf_beg= from->buf;
691
 
  dec1 *end= from->buf + round_up(from->intg) + round_up(from->frac);
 
451
  dec1 *end= from->buf + ROUND_UP(from->intg) + ROUND_UP(from->frac);
692
452
  dec1 *buf_end= end - 1;
693
453
 
694
454
  /* find non-zero digit from number begining */
737
497
}
738
498
 
739
499
 
740
 
/**
741
 
 @param Left shift for alignment of data in buffer
742
 
 
743
 
 @param  dec     pointer to decimal number which have to be shifted
744
 
 @param  shift   number of decimal digits on which it should be shifted
745
 
 @param  beg     beginning of decimal digits (see digits_bounds())
746
 
 @param  end     end of decimal digits (see digits_bounds())
747
 
 
748
 
 @note
749
 
   Result fitting in the buffer should be garanted.
750
 
   'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
751
 
   
752
 
 @todo  Above note is unclear - is 'garanted' a typo for 'guaranteed'
753
 
 or 'granted'?
 
500
/*
 
501
  Left shift for alignment of data in buffer
 
502
 
 
503
  SYNOPSIS
 
504
    do_mini_left_shift()
 
505
    dec     pointer to decimal number which have to be shifted
 
506
    shift   number of decimal digits on which it should be shifted
 
507
    beg/end bounds of decimal digits (see digits_bounds())
 
508
 
 
509
  NOTE
 
510
    Result fitting in the buffer should be garanted.
 
511
    'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
754
512
*/
 
513
 
755
514
static void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
756
515
{
757
 
  dec1 *from= dec->buf + round_up(beg + 1) - 1;
758
 
  dec1 *end= dec->buf + round_up(last) - 1;
 
516
  dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
 
517
  dec1 *end= dec->buf + ROUND_UP(last) - 1;
759
518
  int c_shift= DIG_PER_DEC1 - shift;
760
 
  assert(from >= dec->buf);
761
 
  assert(end < dec->buf + dec->len);
 
519
  DBUG_ASSERT(from >= dec->buf);
 
520
  DBUG_ASSERT(end < dec->buf + dec->len);
762
521
  if (beg % DIG_PER_DEC1 < shift)
763
522
    *(from - 1)= (*from) / powers10[c_shift];
764
523
  for(; from < end; from++)
768
527
}
769
528
 
770
529
 
771
 
/**
772
 
  @brief Right shift for alignment of data in buffer
773
 
 
774
 
  @param  dec     pointer to decimal number which have to be shifted
775
 
  @param  shift   number of decimal digits on which it should be shifted
776
 
  @param  beg     beginning of decimal digits (see digits_bounds())
777
 
  @param  end     end of decimal digits (see digits_bounds())
778
 
 
779
 
  @note
 
530
/*
 
531
  Right shift for alignment of data in buffer
 
532
 
 
533
  SYNOPSIS
 
534
    do_mini_left_shift()
 
535
    dec     pointer to decimal number which have to be shifted
 
536
    shift   number of decimal digits on which it should be shifted
 
537
    beg/end bounds of decimal digits (see digits_bounds())
 
538
 
 
539
  NOTE
780
540
    Result fitting in the buffer should be garanted.
781
541
    'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
782
542
*/
 
543
 
783
544
static void do_mini_right_shift(decimal_t *dec, int shift, int beg, int last)
784
545
{
785
 
  dec1 *from= dec->buf + round_up(last) - 1;
786
 
  dec1 *end= dec->buf + round_up(beg + 1) - 1;
 
546
  dec1 *from= dec->buf + ROUND_UP(last) - 1;
 
547
  dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1;
787
548
  int c_shift= DIG_PER_DEC1 - shift;
788
 
  assert(from < dec->buf + dec->len);
789
 
  assert(end >= dec->buf);
 
549
  DBUG_ASSERT(from < dec->buf + dec->len);
 
550
  DBUG_ASSERT(end >= dec->buf);
790
551
  if (DIG_PER_DEC1 - ((last - 1) % DIG_PER_DEC1 + 1) < shift)
791
552
    *(from + 1)= (*from % powers10[shift]) * powers10[c_shift];
792
553
  for(; from > end; from--)
796
557
}
797
558
 
798
559
 
799
 
/**
800
 
  @brief  Shift of decimal digits in given number (with rounding if it need)
 
560
/*
 
561
  Shift of decimal digits in given number (with rounding if it need)
801
562
 
802
 
  @param  dec       number to be shifted
803
 
  @param  shift     number of decimal positions
 
563
  SYNOPSIS
 
564
    decimal_shift()
 
565
    dec       number to be shifted
 
566
    shift     number of decimal positions
804
567
              shift > 0 means shift to left shift
805
568
              shift < 0 meand right shift
806
 
 
807
 
  @note
 
569
  NOTE
808
570
    In fact it is multipling on 10^shift.
 
571
  RETURN
 
572
    E_DEC_OK          OK
 
573
    E_DEC_OVERFLOW    operation lead to overflow, number is untoched
 
574
    E_DEC_TRUNCATED   number was rounded to fit into buffer
 
575
*/
809
576
 
810
 
  @return  Error code
811
 
   @retval E_DEC_OK          OK
812
 
   @retval E_DEC_OVERFLOW    operation lead to overflow, number is untoched
813
 
   @retval E_DEC_TRUNCATED   number was rounded to fit into buffer
814
 
*/
815
577
static int decimal_shift(decimal_t *dec, int shift)
816
578
{
817
579
  /* index of first non zero digit (all indexes from 0) */
819
581
  /* index of position after last decimal digit */
820
582
  int end;
821
583
  /* index of digit position just after point */
822
 
  int point= round_up(dec->intg) * DIG_PER_DEC1;
 
584
  int point= ROUND_UP(dec->intg) * DIG_PER_DEC1;
823
585
  /* new point position */
824
586
  int new_point= point + shift;
825
587
  /* number of digits in result */
837
599
 
838
600
  if (beg == end)
839
601
  {
840
 
    dec->set_zero();
 
602
    decimal_make_zero(dec);
841
603
    return E_DEC_OK;
842
604
  }
843
605
 
846
608
  digits_frac= end - new_point;
847
609
  set_if_bigger(digits_frac, 0);
848
610
 
849
 
  if ((new_len= round_up(digits_int) + (new_frac_len= round_up(digits_frac))) >
 
611
  if ((new_len= ROUND_UP(digits_int) + (new_frac_len= ROUND_UP(digits_frac))) >
850
612
      dec->len)
851
613
  {
852
614
    int lack= new_len - dec->len;
870
632
        we lost all digits (they will be shifted out of buffer), so we can
871
633
        just return 0
872
634
      */
873
 
      dec->set_zero();
874
 
 
 
635
      decimal_make_zero(dec);
875
636
      return E_DEC_TRUNCATED;
876
637
    }
877
638
  }
894
655
        result
895
656
      */
896
657
      do_left= l_mini_shift <= beg;
897
 
      assert(do_left || (dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
 
658
      DBUG_ASSERT(do_left || (dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
898
659
    }
899
660
    else
900
661
    {
902
663
      l_mini_shift= DIG_PER_DEC1 - r_mini_shift;
903
664
      /* see comment above */
904
665
      do_left= !((dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
905
 
      assert(!do_left || l_mini_shift <= beg);
 
666
      DBUG_ASSERT(!do_left || l_mini_shift <= beg);
906
667
    }
907
668
    if (do_left)
908
669
    {
909
670
      do_mini_left_shift(dec, l_mini_shift, beg, end);
910
 
      mini_shift= (-l_mini_shift);
 
671
      mini_shift=- l_mini_shift;
911
672
    }
912
673
    else
913
674
    {
940
701
    {
941
702
      /* move left */
942
703
      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);
945
 
      assert(to >= dec->buf);
946
 
      assert(barier + d_shift < dec->buf + dec->len);
 
704
      to= dec->buf + (ROUND_UP(beg + 1) - 1 - d_shift);
 
705
      barier= dec->buf + (ROUND_UP(end) - 1 - d_shift);
 
706
      DBUG_ASSERT(to >= dec->buf);
 
707
      DBUG_ASSERT(barier + d_shift < dec->buf + dec->len);
947
708
      for(; to <= barier; to++)
948
709
        *to= *(to + d_shift);
949
710
      for(barier+= d_shift; to <= barier; to++)
954
715
    {
955
716
      /* move right */
956
717
      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;
959
 
      assert(to < dec->buf + dec->len);
960
 
      assert(barier - d_shift >= dec->buf);
 
718
      to= dec->buf + ROUND_UP(end) - 1 + d_shift;
 
719
      barier= dec->buf + ROUND_UP(beg + 1) - 1 + d_shift;
 
720
      DBUG_ASSERT(to < dec->buf + dec->len);
 
721
      DBUG_ASSERT(barier - d_shift >= dec->buf);
961
722
      for(; to >= barier; to--)
962
723
        *to= *(to - d_shift);
963
724
      for(barier-= d_shift; to >= barier; to--)
974
735
 
975
736
    Only one of following 'for' loops will work becouse beg <= end
976
737
  */
977
 
  beg= round_up(beg + 1) - 1;
978
 
  end= round_up(end) - 1;
979
 
  assert(new_point >= 0);
980
 
 
 
738
  beg= ROUND_UP(beg + 1) - 1;
 
739
  end= ROUND_UP(end) - 1;
 
740
  DBUG_ASSERT(new_point >= 0);
 
741
  
981
742
  /* We don't want negative new_point below */
982
743
  if (new_point != 0)
983
 
    new_point= round_up(new_point) - 1;
 
744
    new_point= ROUND_UP(new_point) - 1;
984
745
 
985
746
  if (new_point > end)
986
747
  {
1000
761
}
1001
762
 
1002
763
 
1003
 
/**
1004
 
  @brief  Convert string to decimal
 
764
/*
 
765
  Convert string to decimal
1005
766
 
1006
 
  @param  from    value to convert. Doesn't have to be \0 terminated!
1007
 
  @param  to      decimal where where the result will be stored
 
767
  SYNOPSIS
 
768
    internal_str2decl()
 
769
      from    - value to convert. Doesn't have to be \0 terminated!
 
770
      to      - decimal where where the result will be stored
1008
771
                to->buf and to->len must be set.
1009
 
  @param  end     Pointer to pointer to end of string. Will on return be
 
772
      end     - Pointer to pointer to end of string. Will on return be
1010
773
                set to the char after the last used character
1011
 
  @param  fixed   use to->intg, to->frac as limits for input number
 
774
      fixed   - use to->intg, to->frac as limits for input number
1012
775
 
1013
 
  @note
 
776
  NOTE
1014
777
    to->intg and to->frac can be modified even when fixed=1
1015
778
    (but only decreased, in this case)
1016
779
 
1017
 
  @return
 
780
  RETURN VALUE
1018
781
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_BAD_NUM/E_DEC_OOM
1019
782
    In case of E_DEC_FATAL_ERROR *to is set to decimal zero
1020
783
    (to make error handling easier)
1021
784
*/
 
785
 
1022
786
int
1023
 
internal_str2dec(char *from, decimal_t *to, char **end, bool fixed)
 
787
internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed)
1024
788
{
1025
 
  char *s= from, *s1;
1026
 
  char *end_of_string = *end;
1027
 
  char *endp;
 
789
  const char *s= from, *s1, *endp, *end_of_string= *end;
1028
790
  int i, intg, frac, error, intg1, frac1;
1029
791
  dec1 x,*buf;
1030
792
  sanity(to);
1031
793
 
1032
794
  error= E_DEC_BAD_NUM;                         /* In case of bad number */
1033
 
  while (s < end_of_string && my_isspace(&my_charset_utf8_general_ci, *s))
 
795
  while (s < end_of_string && my_isspace(&my_charset_latin1, *s))
1034
796
    s++;
1035
797
  if (s == end_of_string)
1036
798
    goto fatal_error;
1041
803
    s++;
1042
804
 
1043
805
  s1=s;
1044
 
  while (s < end_of_string && my_isdigit(&my_charset_utf8_general_ci, *s))
 
806
  while (s < end_of_string && my_isdigit(&my_charset_latin1, *s))
1045
807
    s++;
1046
808
  intg= (int) (s-s1);
1047
809
  if (s < end_of_string && *s=='.')
1048
810
  {
1049
811
    endp= s+1;
1050
 
    while (endp < end_of_string && my_isdigit(&my_charset_utf8_general_ci, *endp))
 
812
    while (endp < end_of_string && my_isdigit(&my_charset_latin1, *endp))
1051
813
      endp++;
1052
814
    frac= (int) (endp - s - 1);
1053
815
  }
1057
819
    endp= s;
1058
820
  }
1059
821
 
1060
 
  *end= endp;
 
822
  *end= (char*) endp;
1061
823
 
1062
824
  if (frac+intg == 0)
1063
825
    goto fatal_error;
1075
837
      error=E_DEC_OVERFLOW;
1076
838
      intg=to->intg;
1077
839
    }
1078
 
    intg1=round_up(intg);
1079
 
    frac1=round_up(frac);
 
840
    intg1=ROUND_UP(intg);
 
841
    frac1=ROUND_UP(frac);
1080
842
    if (intg1+frac1 > to->len)
1081
843
    {
1082
844
      error= E_DEC_OOM;
1085
847
  }
1086
848
  else
1087
849
  {
1088
 
    intg1=round_up(intg);
1089
 
    frac1=round_up(frac);
1090
 
    fix_intg_frac_error(to->len, intg1, frac1, error);
 
850
    intg1=ROUND_UP(intg);
 
851
    frac1=ROUND_UP(frac);
 
852
    FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
1091
853
    if (unlikely(error))
1092
854
    {
1093
855
      frac=frac1*DIG_PER_DEC1;
1135
897
  if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
1136
898
  {
1137
899
    int str_error;
1138
 
    const int64_t exponent= internal::my_strtoll10(endp+1, (char**) &end_of_string,
1139
 
                                                   &str_error);
 
900
    int64_t exponent= my_strtoll10(endp+1, (char**) &end_of_string,
 
901
                                    &str_error);
1140
902
 
1141
903
    if (end_of_string != endp +1)               /* If at least one digit */
1142
904
    {
1163
925
  return error;
1164
926
 
1165
927
fatal_error:
1166
 
  to->set_zero();
 
928
  decimal_make_zero(to);
1167
929
  return error;
1168
930
}
1169
931
 
1170
932
 
1171
 
/**
1172
 
  @param Convert decimal to double
1173
 
 
1174
 
  @param[in]   from   value to convert
1175
 
  @param[out]  to     result will be stored there
1176
 
 
1177
 
  @return
 
933
/*
 
934
  Convert decimal to double
 
935
 
 
936
  SYNOPSIS
 
937
    decimal2double()
 
938
      from    - value to convert
 
939
      to      - result will be stored there
 
940
 
 
941
  RETURN VALUE
1178
942
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1179
943
*/
1180
944
 
1181
 
int decimal2double(const decimal_t *from, double *to)
 
945
int decimal2double(decimal_t *from, double *to)
1182
946
{
1183
947
  char strbuf[FLOATING_POINT_BUFFER], *end;
1184
948
  int len= sizeof(strbuf);
1186
950
 
1187
951
  rc = decimal2string(from, strbuf, &len, 0, 0, 0);
1188
952
  end= strbuf + len;
 
953
  
 
954
  DBUG_PRINT("info", ("interm.: %s", strbuf));
1189
955
 
1190
 
  *to= internal::my_strtod(strbuf, &end, &error);
 
956
  *to= my_strtod(strbuf, &end, &error);
 
957
             
 
958
  DBUG_PRINT("info", ("result: %f (%lx)", *to, *(ulong *)to));
1191
959
 
1192
960
  return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
1193
961
}
1194
962
 
1195
 
/**
1196
 
 @param  Convert double to decimal
1197
 
 
1198
 
 @param[in]  from    value to convert
1199
 
 @param[out] to      result will be stored there
1200
 
 
1201
 
 @return
 
963
/*
 
964
  Convert double to decimal
 
965
 
 
966
  SYNOPSIS
 
967
    double2decimal()
 
968
      from    - value to convert
 
969
      to      - result will be stored there
 
970
 
 
971
  RETURN VALUE
1202
972
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1203
973
*/
1204
974
 
1205
 
int double2decimal(const double from, decimal_t *to)
 
975
int double2decimal(double from, decimal_t *to)
1206
976
{
1207
977
  char buff[FLOATING_POINT_BUFFER], *end;
1208
978
  int res;
1209
 
  end= buff + internal::my_gcvt(from,
1210
 
                                internal::MY_GCVT_ARG_DOUBLE,
1211
 
                                sizeof(buff) - 1, buff, NULL);
 
979
  DBUG_ENTER("double2decimal");
 
980
  end= buff + my_gcvt(from, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
1212
981
  res= string2decimal(buff, to, &end);
1213
 
  return(res);
 
982
  DBUG_PRINT("exit", ("res: %d", res));
 
983
  DBUG_RETURN(res);
1214
984
}
1215
985
 
1216
986
 
1240
1010
  return error;
1241
1011
}
1242
1012
 
1243
 
int uint64_t2decimal(const uint64_t from, decimal_t *to)
 
1013
int uint64_t2decimal(uint64_t from, decimal_t *to)
1244
1014
{
1245
1015
  to->sign=0;
1246
1016
  return ull2dec(from, to);
1247
1017
}
1248
1018
 
1249
 
int int64_t2decimal(const int64_t from, decimal_t *to)
 
1019
int int64_t2decimal(int64_t from, decimal_t *to)
1250
1020
{
1251
1021
  if ((to->sign= from < 0))
1252
1022
    return ull2dec(-from, to);
1253
1023
  return ull2dec(from, to);
1254
1024
}
1255
1025
 
1256
 
int decimal2uint64_t(const decimal_t *from, uint64_t *to)
 
1026
int decimal2uint64_t(decimal_t *from, uint64_t *to)
1257
1027
{
1258
1028
  dec1 *buf=from->buf;
1259
1029
  uint64_t x=0;
1282
1052
  return E_DEC_OK;
1283
1053
}
1284
1054
 
1285
 
int decimal2int64_t(const decimal_t *from, int64_t *to)
 
1055
int decimal2int64_t(decimal_t *from, int64_t *to)
1286
1056
{
1287
1057
  dec1 *buf=from->buf;
1288
1058
  int64_t x=0;
1322
1092
  return E_DEC_OK;
1323
1093
}
1324
1094
 
1325
 
/**
1326
 
 @brief
1327
 
  Convert decimal to its binary fixed-length representation (suitable for
1328
 
  comparing with memcmp)
1329
 
 
 
1095
/*
 
1096
  Convert decimal to its binary fixed-length representation
 
1097
  two representations of the same length can be compared with memcmp
 
1098
  with the correct -1/0/+1 result
 
1099
 
 
1100
  SYNOPSIS
 
1101
    decimal2bin()
 
1102
      from    - value to convert
 
1103
      to      - points to buffer where string representation should be stored
 
1104
      precision/scale - see decimal_bin_size() below
 
1105
 
 
1106
  NOTE
 
1107
    the buffer is assumed to be of the size decimal_bin_size(precision, scale)
 
1108
 
 
1109
  RETURN VALUE
 
1110
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
 
1111
 
 
1112
  DESCRIPTION
1330
1113
    for storage decimal numbers are converted to the "binary" format.
1331
1114
 
1332
1115
    This format has the following properties:
1387
1170
    And for -1234567890.1234 it would be
1388
1171
 
1389
1172
                7E F2 04 37 2D FB 2D
1390
 
 
1391
 
 
1392
 
  @param from      value to convert
1393
 
  @param to        points to buffer where string representation should be stored
1394
 
  @param precision see decimal_bin_size() below
1395
 
  @param frac      see decimal_bin_size() below
1396
 
 
1397
 
  @note
1398
 
    The buffer is assumed to be of the size decimal_bin_size(precision, scale)
1399
 
 
1400
 
  @return
1401
 
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1402
 
 
1403
1173
*/
1404
 
int decimal2bin(const decimal_t *from, unsigned char *to, int precision, int frac)
 
1174
int decimal2bin(decimal_t *from, uchar *to, int precision, int frac)
1405
1175
{
1406
1176
  dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1407
1177
  int error=E_DEC_OK, intg=precision-frac,
1417
1187
      fsize1=frac1*sizeof(dec1)+dig2bytes[frac1x];
1418
1188
  const int orig_isize0= isize0;
1419
1189
  const int orig_fsize0= fsize0;
1420
 
  unsigned char *orig_to= to;
 
1190
  uchar *orig_to= to;
1421
1191
 
1422
1192
  buf1= remove_leading_zeroes(from, &from_intg);
1423
1193
 
1473
1243
      case 2: mi_int2store(to, x); break;
1474
1244
      case 3: mi_int3store(to, x); break;
1475
1245
      case 4: mi_int4store(to, x); break;
1476
 
      default: assert(0);
 
1246
      default: DBUG_ASSERT(0);
1477
1247
    }
1478
1248
    to+=i;
1479
1249
  }
1482
1252
  for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=sizeof(dec1))
1483
1253
  {
1484
1254
    dec1 x=*buf1++ ^ mask;
1485
 
    assert(sizeof(dec1) == 4);
 
1255
    DBUG_ASSERT(sizeof(dec1) == 4);
1486
1256
    mi_int4store(to, x);
1487
1257
  }
1488
1258
 
1501
1271
      case 2: mi_int2store(to, x); break;
1502
1272
      case 3: mi_int3store(to, x); break;
1503
1273
      case 4: mi_int4store(to, x); break;
1504
 
      default: assert(0);
 
1274
      default: DBUG_ASSERT(0);
1505
1275
    }
1506
1276
    to+=i;
1507
1277
  }
1508
1278
  if (fsize0 > fsize1)
1509
1279
  {
1510
 
    unsigned char *to_end= orig_to + orig_fsize0 + orig_isize0;
 
1280
    uchar *to_end= orig_to + orig_fsize0 + orig_isize0;
1511
1281
 
1512
1282
    while (fsize0-- > fsize1 && to < to_end)
1513
 
      *to++= (unsigned char)mask;
 
1283
      *to++= (uchar)mask;
1514
1284
  }
1515
1285
  orig_to[0]^= 0x80;
1516
1286
 
1517
1287
  /* Check that we have written the whole decimal and nothing more */
1518
 
  assert(to == orig_to + orig_fsize0 + orig_isize0);
 
1288
  DBUG_ASSERT(to == orig_to + orig_fsize0 + orig_isize0);
1519
1289
  return error;
1520
1290
}
1521
1291
 
1522
 
/**
1523
 
 @brief Restores decimal from its binary fixed-length representation
1524
 
 
1525
 
 @param  from    value to convert
1526
 
 @param  to      result
1527
 
 @param  precision see decimal_bin_size() below
1528
 
 @param  scale     see decimal_bin_size() below
1529
 
 
1530
 
 @note
 
1292
/*
 
1293
  Restores decimal from its binary fixed-length representation
 
1294
 
 
1295
  SYNOPSIS
 
1296
    bin2decimal()
 
1297
      from    - value to convert
 
1298
      to      - result
 
1299
      precision/scale - see decimal_bin_size() below
 
1300
 
 
1301
  NOTE
1531
1302
    see decimal2bin()
1532
1303
    the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1533
1304
 
1534
 
 @return
 
1305
  RETURN VALUE
1535
1306
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1536
1307
*/
1537
 
int bin2decimal(const unsigned char *from, decimal_t *to, int precision, int scale)
 
1308
 
 
1309
int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale)
1538
1310
{
1539
1311
  int error=E_DEC_OK, intg=precision-scale,
1540
1312
      intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1541
1313
      intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
1542
1314
      intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
1543
1315
  dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
1544
 
  const unsigned char *stop;
1545
 
  unsigned char *d_copy;
 
1316
  const uchar *stop;
 
1317
  uchar *d_copy;
1546
1318
  int bin_size= decimal_bin_size(precision, scale);
1547
1319
 
1548
1320
  sanity(to);
1549
 
  d_copy= (unsigned char*) alloca(bin_size);
 
1321
  d_copy= (uchar*) my_alloca(bin_size);
1550
1322
  memcpy(d_copy, from, bin_size);
1551
1323
  d_copy[0]^= 0x80;
1552
1324
  from= d_copy;
1553
1325
 
1554
 
  fix_intg_frac_error(to->len, intg1, frac1, error);
 
1326
  FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
1555
1327
  if (unlikely(error))
1556
1328
  {
1557
1329
    if (intg1 < intg0+(intg0x>0))
1581
1353
      case 2: x=mi_sint2korr(from); break;
1582
1354
      case 3: x=mi_sint3korr(from); break;
1583
1355
      case 4: x=mi_sint4korr(from); break;
1584
 
      default: assert(0);
 
1356
      default: DBUG_ASSERT(0);
1585
1357
    }
1586
1358
    from+=i;
1587
1359
    *buf=x ^ mask;
1594
1366
  }
1595
1367
  for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1596
1368
  {
1597
 
    assert(sizeof(dec1) == 4);
 
1369
    DBUG_ASSERT(sizeof(dec1) == 4);
1598
1370
    *buf=mi_sint4korr(from) ^ mask;
1599
 
    if (((uint32_t)*buf) > DIG_MAX)
 
1371
    if (((uint32)*buf) > DIG_MAX)
1600
1372
      goto err;
1601
1373
    if (buf > to->buf || *buf != 0)
1602
1374
      buf++;
1603
1375
    else
1604
1376
      to->intg-=DIG_PER_DEC1;
1605
1377
  }
1606
 
  assert(to->intg >=0);
 
1378
  DBUG_ASSERT(to->intg >=0);
1607
1379
  for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1))
1608
1380
  {
1609
 
    assert(sizeof(dec1) == 4);
 
1381
    DBUG_ASSERT(sizeof(dec1) == 4);
1610
1382
    *buf=mi_sint4korr(from) ^ mask;
1611
 
    if (((uint32_t)*buf) > DIG_MAX)
 
1383
    if (((uint32)*buf) > DIG_MAX)
1612
1384
      goto err;
1613
1385
    buf++;
1614
1386
  }
1622
1394
      case 2: x=mi_sint2korr(from); break;
1623
1395
      case 3: x=mi_sint3korr(from); break;
1624
1396
      case 4: x=mi_sint4korr(from); break;
1625
 
      default: assert(0);
 
1397
      default: DBUG_ASSERT(0);
1626
1398
    }
1627
1399
    *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
1628
 
    if (((uint32_t)*buf) > DIG_MAX)
 
1400
    if (((uint32)*buf) > DIG_MAX)
1629
1401
      goto err;
1630
1402
    buf++;
1631
1403
  }
 
1404
  my_afree(d_copy);
1632
1405
  return error;
1633
1406
 
1634
1407
err:
1635
 
  to->set_zero();
 
1408
  my_afree(d_copy);
 
1409
  decimal_make_zero(((decimal_t*) to));
1636
1410
  return(E_DEC_BAD_NUM);
1637
1411
}
1638
1412
 
1639
 
/**
1640
 
 @brief  Returns the size of array to hold a binary representation of a decimal
1641
 
 
1642
 
 @return  Size in bytes
1643
 
*/
 
1413
/*
 
1414
  Returns the size of array to hold a decimal with given precision and scale
 
1415
 
 
1416
  RETURN VALUE
 
1417
    size in dec1
 
1418
    (multiply by sizeof(dec1) to get the size if bytes)
 
1419
*/
 
1420
 
 
1421
int decimal_size(int precision, int scale)
 
1422
{
 
1423
  DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
 
1424
  return ROUND_UP(precision-scale)+ROUND_UP(scale);
 
1425
}
 
1426
 
 
1427
/*
 
1428
  Returns the size of array to hold a binary representation of a decimal
 
1429
 
 
1430
  RETURN VALUE
 
1431
    size in bytes
 
1432
*/
 
1433
 
1644
1434
int decimal_bin_size(int precision, int scale)
1645
1435
{
1646
1436
  int intg=precision-scale,
1647
1437
      intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1648
1438
      intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1;
1649
1439
 
1650
 
  assert(scale >= 0 && precision > 0 && scale <= precision);
 
1440
  DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
1651
1441
  return intg0*sizeof(dec1)+dig2bytes[intg0x]+
1652
1442
         frac0*sizeof(dec1)+dig2bytes[frac0x];
1653
1443
}
1654
1444
 
1655
 
/**
1656
 
 @brief  Rounds the decimal to "scale" digits
1657
 
 
1658
 
 @param from    - decimal to round,
1659
 
 @param to      - result buffer. from==to is allowed
1660
 
 @param scale   - to what position to round. can be negative!
1661
 
 @param mode    - round to nearest even or truncate
1662
 
 
1663
 
 @note
 
1445
/*
 
1446
  Rounds the decimal to "scale" digits
 
1447
 
 
1448
  SYNOPSIS
 
1449
    decimal_round()
 
1450
      from    - decimal to round,
 
1451
      to      - result buffer. from==to is allowed
 
1452
      scale   - to what position to round. can be negative!
 
1453
      mode    - round to nearest even or truncate
 
1454
 
 
1455
  NOTES
1664
1456
    scale can be negative !
1665
1457
    one TRUNCATED error (line XXX below) isn't treated very logical :(
1666
1458
 
1667
 
 @return
 
1459
  RETURN VALUE
1668
1460
    E_DEC_OK/E_DEC_TRUNCATED
1669
1461
*/
 
1462
 
1670
1463
int
1671
 
decimal_round(const decimal_t *from, decimal_t *to, int scale,
 
1464
decimal_round(decimal_t *from, decimal_t *to, int scale,
1672
1465
              decimal_round_mode mode)
1673
1466
{
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 +
 
1467
  int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
 
1468
      frac1=ROUND_UP(from->frac), round_digit= 0,
 
1469
      intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len,
 
1470
      intg1=ROUND_UP(from->intg +
1678
1471
                     (((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX)));
1679
1472
  dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
1680
1473
  int first_dig;
1687
1480
  case CEILING:         round_digit= from->sign ? 10 : 0; break;
1688
1481
  case FLOOR:           round_digit= from->sign ? 0 : 10; break;
1689
1482
  case TRUNCATE:        round_digit=10; break;
1690
 
  default: assert(0);
 
1483
  default: DBUG_ASSERT(0);
1691
1484
  }
1692
1485
 
1693
1486
  if (unlikely(frac0+intg0 > len))
1699
1492
 
1700
1493
  if (scale+from->intg < 0)
1701
1494
  {
1702
 
    to->set_zero();
 
1495
    decimal_make_zero(to);
1703
1496
    return E_DEC_OK;
1704
1497
  }
1705
1498
 
1736
1529
  if (scale == frac0*DIG_PER_DEC1)
1737
1530
  {
1738
1531
    int do_inc= false;
1739
 
    assert(frac0+intg0 >= 0);
 
1532
    DBUG_ASSERT(frac0+intg0 >= 0);
1740
1533
    switch (round_digit) {
1741
1534
    case 0:
1742
1535
    {
1770
1563
    }
1771
1564
    else if (frac0+intg0==0)
1772
1565
    {
1773
 
      to->set_zero();
 
1566
      decimal_make_zero(to);
1774
1567
      return E_DEC_OK;
1775
1568
    }
1776
1569
  }
1777
1570
  else
1778
1571
  {
1779
 
  /** @todo fix this code as it won't work for CEILING mode */
 
1572
    /* TODO - fix this code as it won't work for CEILING mode */
1780
1573
    int pos=frac0*DIG_PER_DEC1-scale-1;
1781
 
    assert(frac0+intg0 > 0);
 
1574
    DBUG_ASSERT(frac0+intg0 > 0);
1782
1575
    x=*buf1 / powers10[pos];
1783
1576
    y=x % 10;
1784
1577
    if (y > round_digit ||
1809
1602
    carry=1;
1810
1603
    *buf1-=DIG_BASE;
1811
1604
    while (carry && --buf1 >= to->buf)
1812
 
      add(*buf1, *buf1, 0, carry);
 
1605
      ADD(*buf1, *buf1, 0, carry);
1813
1606
    if (unlikely(carry))
1814
1607
    {
1815
1608
      /* shifting the number to create space for new digit */
1860
1653
  return error;
1861
1654
}
1862
1655
 
1863
 
static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1864
 
{
1865
 
  int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
1866
 
      frac1=round_up(from1->frac), frac2=round_up(from2->frac),
 
1656
/*
 
1657
  Returns the size of the result of the operation
 
1658
 
 
1659
  SYNOPSIS
 
1660
    decimal_result_size()
 
1661
      from1   - operand of the unary operation or first operand of the
 
1662
                binary operation
 
1663
      from2   - second operand of the binary operation
 
1664
      op      - operation. one char '+', '-', '*', '/' are allowed
 
1665
                others may be added later
 
1666
      param   - extra param to the operation. unused for '+', '-', '*'
 
1667
                scale increment for '/'
 
1668
 
 
1669
  NOTE
 
1670
    returned valued may be larger than the actual buffer requred
 
1671
    in the operation, as decimal_result_size, by design, operates on
 
1672
    precision/scale values only and not on the actual decimal number
 
1673
 
 
1674
  RETURN VALUE
 
1675
    size of to->buf array in dec1 elements. to get size in bytes
 
1676
    multiply by sizeof(dec1)
 
1677
*/
 
1678
 
 
1679
int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param)
 
1680
{
 
1681
  switch (op) {
 
1682
  case '-':
 
1683
    return ROUND_UP(max(from1->intg, from2->intg)) +
 
1684
           ROUND_UP(max(from1->frac, from2->frac));
 
1685
  case '+':
 
1686
    return ROUND_UP(max(from1->intg, from2->intg)+1) +
 
1687
           ROUND_UP(max(from1->frac, from2->frac));
 
1688
  case '*':
 
1689
    return ROUND_UP(from1->intg+from2->intg)+
 
1690
           ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
 
1691
  case '/':
 
1692
    return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param);
 
1693
  default: DBUG_ASSERT(0);
 
1694
  }
 
1695
  return -1; /* shut up the warning */
 
1696
}
 
1697
 
 
1698
static int do_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
 
1699
{
 
1700
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
 
1701
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1867
1702
      frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
1868
1703
  dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
1869
1704
 
1879
1714
    to->buf[0]=0; /* safety */
1880
1715
  }
1881
1716
 
1882
 
  fix_intg_frac_error(to->len, intg0, frac0, error);
 
1717
  FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
1883
1718
  if (unlikely(error == E_DEC_OVERFLOW))
1884
1719
  {
1885
1720
    max_decimal(to->len * DIG_PER_DEC1, 0, to);
1900
1735
    set_if_smaller(intg2, intg0);
1901
1736
  }
1902
1737
 
1903
 
  /* part 1 - cmax(frac) ... cmin(frac) */
 
1738
  /* part 1 - max(frac) ... min (frac) */
1904
1739
  if (frac1 > frac2)
1905
1740
  {
1906
1741
    buf1=from1->buf+intg1+frac1;
1918
1753
  while (buf1 > stop)
1919
1754
    *--buf0=*--buf1;
1920
1755
 
1921
 
  /* part 2 - cmin(frac) ... cmin(intg) */
 
1756
  /* part 2 - min(frac) ... min(intg) */
1922
1757
  carry=0;
1923
1758
  while (buf1 > stop2)
1924
1759
  {
1925
 
    add(*--buf0, *--buf1, *--buf2, carry);
 
1760
    ADD(*--buf0, *--buf1, *--buf2, carry);
1926
1761
  }
1927
1762
 
1928
 
  /* part 3 - cmin(intg) ... cmax(intg) */
 
1763
  /* part 3 - min(intg) ... max(intg) */
1929
1764
  buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
1930
1765
                        ((stop=from2->buf)+intg2-intg1) ;
1931
1766
  while (buf1 > stop)
1932
1767
  {
1933
 
    add(*--buf0, *--buf1, 0, carry);
 
1768
    ADD(*--buf0, *--buf1, 0, carry);
1934
1769
  }
1935
1770
 
1936
1771
  if (unlikely(carry))
1937
1772
    *--buf0=1;
1938
 
  assert(buf0 == to->buf || buf0 == to->buf+1);
 
1773
  DBUG_ASSERT(buf0 == to->buf || buf0 == to->buf+1);
1939
1774
 
1940
1775
  return error;
1941
1776
}
1942
1777
 
1943
1778
/* to=from1-from2.
1944
1779
   if to==0, return -1/0/+1 - the result of the comparison */
1945
 
static int do_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1780
static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
1946
1781
{
1947
 
  int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
1948
 
      frac1=round_up(from1->frac), frac2=round_up(from2->frac);
 
1782
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
 
1783
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
1949
1784
  int frac0=max(frac1, frac2), error;
1950
1785
  dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
1951
1786
 
1995
1830
      {
1996
1831
        if (to == 0) /* decimal_cmp() */
1997
1832
          return 0;
1998
 
 
1999
 
        to->set_zero();
2000
 
 
 
1833
        decimal_make_zero(to);
2001
1834
        return E_DEC_OK;
2002
1835
      }
2003
1836
    }
2013
1846
  /* ensure that always from1 > from2 (and intg1 >= intg2) */
2014
1847
  if (carry)
2015
1848
  {
2016
 
    swap(from1, from2);
2017
 
    swap(start1, start2);
2018
 
    swap(intg1, intg2);
2019
 
    swap(frac1, frac2);
 
1849
    swap_variables(decimal_t *,from1,from1);
 
1850
    swap_variables(dec1 *,start1, start2);
 
1851
    swap_variables(int,intg1,intg2);
 
1852
    swap_variables(int,frac1,frac2);
2020
1853
    to->sign= 1 - to->sign;
2021
1854
  }
2022
1855
 
2023
 
  fix_intg_frac_error(to->len, intg1, frac0, error);
 
1856
  FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
2024
1857
  buf0=to->buf+intg1+frac0;
2025
1858
 
2026
1859
  to->frac=max(from1->frac, from2->frac);
2034
1867
  }
2035
1868
  carry=0;
2036
1869
 
2037
 
  /* part 1 - cmax(frac) ... cmin(frac) */
 
1870
  /* part 1 - max(frac) ... min (frac) */
2038
1871
  if (frac1 > frac2)
2039
1872
  {
2040
1873
    buf1=start1+intg1+frac1;
2054
1887
      *--buf0=0;
2055
1888
    while (buf2 > stop2)
2056
1889
    {
2057
 
      sub(*--buf0, 0, *--buf2, carry);
 
1890
      SUB(*--buf0, 0, *--buf2, carry);
2058
1891
    }
2059
1892
  }
2060
1893
 
2061
 
  /* part 2 - cmin(frac) ... intg2 */
 
1894
  /* part 2 - min(frac) ... intg2 */
2062
1895
  while (buf2 > start2)
2063
1896
  {
2064
 
    sub(*--buf0, *--buf1, *--buf2, carry);
 
1897
    SUB(*--buf0, *--buf1, *--buf2, carry);
2065
1898
  }
2066
1899
 
2067
1900
  /* part 3 - intg2 ... intg1 */
2068
1901
  while (carry && buf1 > start1)
2069
1902
  {
2070
 
    sub(*--buf0, *--buf1, 0, carry);
 
1903
    SUB(*--buf0, *--buf1, 0, carry);
2071
1904
  }
2072
1905
 
2073
1906
  while (buf1 > start1)
2079
1912
  return error;
2080
1913
}
2081
1914
 
2082
 
int decimal_intg(const decimal_t *from)
 
1915
int decimal_intg(decimal_t *from)
2083
1916
{
2084
1917
  int res;
2085
1918
  dec1 *tmp_res;
2087
1920
  return res;
2088
1921
}
2089
1922
 
2090
 
int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1923
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
2091
1924
{
2092
1925
  if (likely(from1->sign == from2->sign))
2093
1926
    return do_add(from1, from2, to);
2094
1927
  return do_sub(from1, from2, to);
2095
1928
}
2096
1929
 
2097
 
int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1930
int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
2098
1931
{
2099
1932
  if (likely(from1->sign == from2->sign))
2100
1933
    return do_sub(from1, from2, to);
2101
1934
  return do_add(from1, from2, to);
2102
1935
}
2103
1936
 
2104
 
int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
 
1937
int decimal_cmp(decimal_t *from1, decimal_t *from2)
2105
1938
{
2106
1939
  if (likely(from1->sign == from2->sign))
2107
1940
    return do_sub(from1, from2, 0);
2108
1941
  return from1->sign > from2->sign ? -1 : 1;
2109
1942
}
2110
1943
 
2111
 
int decimal_t::isZero() const
 
1944
int decimal_is_zero(decimal_t *from)
2112
1945
{
2113
 
  dec1 *buf1= buf,
2114
 
       *end= buf1 +round_up(intg) +round_up(frac);
2115
 
 
 
1946
  dec1 *buf1=from->buf,
 
1947
       *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2116
1948
  while (buf1 < end)
2117
 
  {
2118
1949
    if (*buf1++)
2119
 
    {
2120
1950
      return 0;
2121
 
    }
2122
 
  }
2123
 
 
2124
1951
  return 1;
2125
1952
}
2126
1953
 
2127
 
/**
2128
 
 @brief multiply two decimals
2129
 
 
2130
 
 @param[in]   from1  First factor
2131
 
 @param[in]   from2  Second factor
2132
 
 @param[out]  to     product
2133
 
 
2134
 
 @return
 
1954
/*
 
1955
  multiply two decimals
 
1956
 
 
1957
  SYNOPSIS
 
1958
    decimal_mul()
 
1959
      from1, from2 - factors
 
1960
      to      - product
 
1961
 
 
1962
  RETURN VALUE
2135
1963
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
2136
1964
 
2137
 
 @note
 
1965
  NOTES
2138
1966
    in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
2139
1967
    and 63-digit number will take only 7 dec1 words (basically a 7-digit
2140
1968
    "base 999999999" number).  Thus there's no need in fast multiplication
2144
1972
    XXX if this library is to be used with huge numbers of thousands of
2145
1973
    digits, fast multiplication must be implemented.
2146
1974
*/
2147
 
int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
1975
int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to)
2148
1976
{
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),
 
1977
  int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
 
1978
      frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
 
1979
      intg0=ROUND_UP(from1->intg+from2->intg),
2152
1980
      frac0=frac1+frac2, error, i, j, d_to_move;
2153
1981
  dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
2154
1982
       *start2, *stop2, *stop1, *start0, carry;
2157
1985
 
2158
1986
  i=intg0;
2159
1987
  j=frac0;
2160
 
  fix_intg_frac_error(to->len, intg0, frac0, error);
 
1988
  FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2161
1989
  to->sign=from1->sign != from2->sign;
2162
1990
  to->frac=from1->frac+from2->frac;
2163
1991
  to->intg=intg0*DIG_PER_DEC1;
2187
2015
  stop1=buf1-intg1;
2188
2016
  stop2=buf2-intg2;
2189
2017
 
2190
 
  memset(to->buf, 0, (intg0+frac0)*sizeof(dec1));
 
2018
  bzero(to->buf, (intg0+frac0)*sizeof(dec1));
2191
2019
 
2192
2020
  for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
2193
2021
  {
2198
2026
      dec2 p= ((dec2)*buf1) * ((dec2)*buf2);
2199
2027
      hi=(dec1)(p/DIG_BASE);
2200
2028
      lo=(dec1)(p-((dec2)hi)*DIG_BASE);
2201
 
      add2(*buf0, *buf0, lo, carry);
 
2029
      ADD2(*buf0, *buf0, lo, carry);
2202
2030
      carry+=hi;
2203
2031
    }
2204
2032
    if (carry)
2205
2033
    {
2206
2034
      if (buf0 < to->buf)
2207
2035
        return E_DEC_OVERFLOW;
2208
 
      add2(*buf0, *buf0, 0, carry);
 
2036
      ADD2(*buf0, *buf0, 0, carry);
2209
2037
    }
2210
2038
    for (buf0--; carry; buf0--)
2211
2039
    {
2212
2040
      if (buf0 < to->buf)
2213
2041
        return E_DEC_OVERFLOW;
2214
 
      add(*buf0, *buf0, 0, carry);
 
2042
      ADD(*buf0, *buf0, 0, carry);
2215
2043
    }
2216
2044
  }
2217
2045
 
2220
2048
  {
2221
2049
    dec1 *buf= to->buf;
2222
2050
    dec1 *end= to->buf + intg0 + frac0;
2223
 
    assert(buf != end);
 
2051
    DBUG_ASSERT(buf != end);
2224
2052
    for (;;)
2225
2053
    {
2226
2054
      if (*buf)
2228
2056
      if (++buf == end)
2229
2057
      {
2230
2058
        /* We got decimal zero */
2231
 
        to->set_zero();
 
2059
        decimal_make_zero(to);
2232
2060
        break;
2233
2061
      }
2234
2062
    }
2235
2063
  }
2236
2064
  buf1= to->buf;
2237
 
  d_to_move= intg0 + round_up(to->frac);
 
2065
  d_to_move= intg0 + ROUND_UP(to->frac);
2238
2066
  while (!*buf1 && (to->intg > DIG_PER_DEC1))
2239
2067
  {
2240
2068
    buf1++;
2250
2078
  return error;
2251
2079
}
2252
2080
 
2253
 
/**
 
2081
/*
2254
2082
  naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2255
2083
  it's ok for short numbers
2256
2084
  also we're using alloca() to allocate a temporary buffer
2257
2085
 
2258
 
  @todo
2259
 
  If this library is to be used with huge numbers of thousands of
 
2086
  XXX if this library is to be used with huge numbers of thousands of
2260
2087
  digits, fast division must be implemented and alloca should be
2261
2088
  changed to malloc (or at least fallback to malloc if alloca() fails)
2262
2089
  but then, decimal_mul() should be rewritten too :(
2263
2090
*/
2264
 
static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
 
2091
static int do_div_mod(decimal_t *from1, decimal_t *from2,
2265
2092
                       decimal_t *to, decimal_t *mod, int scale_incr)
2266
2093
{
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,
 
2094
  int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
 
2095
      frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2269
2096
      error= 0, i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2270
2097
  dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2271
2098
       *start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
2287
2114
  if (prec2 <= 0) /* short-circuit everything: from2 == 0 */
2288
2115
    return E_DEC_DIV_ZERO;
2289
2116
  for (i= (prec2 - 1) % DIG_PER_DEC1; *buf2 < powers10[i--]; prec2--) ;
2290
 
  assert(prec2 > 0);
 
2117
  DBUG_ASSERT(prec2 > 0);
2291
2118
 
2292
2119
  i=((prec1-1) % DIG_PER_DEC1)+1;
2293
2120
  while (prec1 > 0 && *buf1 == 0)
2298
2125
  }
2299
2126
  if (prec1 <= 0)
2300
2127
  { /* short-circuit everything: from1 == 0 */
2301
 
    to->set_zero();
 
2128
    decimal_make_zero(to);
2302
2129
    return E_DEC_OK;
2303
2130
  }
2304
2131
  for (i=(prec1-1) % DIG_PER_DEC1; *buf1 < powers10[i--]; prec1--) ;
2305
 
  assert(prec1 > 0);
 
2132
  DBUG_ASSERT(prec1 > 0);
2306
2133
 
2307
2134
  /* let's fix scale_incr, taking into account frac1,frac2 increase */
2308
2135
  if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0)
2315
2142
    intg0=0;
2316
2143
  }
2317
2144
  else
2318
 
    intg0=round_up(dintg);
 
2145
    intg0=ROUND_UP(dintg);
2319
2146
  if (mod)
2320
2147
  {
2321
2148
    /* we're calculating N1 % N2.
2322
2149
       The result will have
2323
 
         frac=cmax(frac1, frac2), as for subtraction
 
2150
         frac=max(frac1, frac2), as for subtraction
2324
2151
         intg=intg2
2325
2152
    */
2326
2153
    to->sign=from1->sign;
2334
2161
      N2 is in the buf2, has prec2 digits. Scales are frac1 and
2335
2162
      frac2 accordingly.
2336
2163
      Thus, the result will have
2337
 
         frac = round_up(frac1+frac2+scale_incr)
 
2164
         frac = ROUND_UP(frac1+frac2+scale_incr)
2338
2165
      and
2339
2166
         intg = (prec1-frac1) - (prec2-frac2) + 1
2340
2167
         prec = intg+frac
2341
2168
    */
2342
 
    frac0=round_up(frac1+frac2+scale_incr);
2343
 
    fix_intg_frac_error(to->len, intg0, frac0, error);
 
2169
    frac0=ROUND_UP(frac1+frac2+scale_incr);
 
2170
    FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2344
2171
    to->sign=from1->sign != from2->sign;
2345
2172
    to->intg=intg0*DIG_PER_DEC1;
2346
2173
    to->frac=frac0*DIG_PER_DEC1;
2351
2178
    while (dintg++ < 0)
2352
2179
      *buf0++=0;
2353
2180
 
2354
 
  len1=(i=round_up(prec1))+round_up(2*frac2+scale_incr+1) + 1;
 
2181
  len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1;
2355
2182
  set_if_bigger(len1, 3);
2356
 
  if (!(tmp1=(dec1 *)alloca(len1*sizeof(dec1))))
 
2183
  if (!(tmp1=(dec1 *)my_alloca(len1*sizeof(dec1))))
2357
2184
    return E_DEC_OOM;
2358
2185
  memcpy(tmp1, buf1, i*sizeof(dec1));
2359
 
  memset(tmp1+i, 0, (len1-i)*sizeof(dec1));
 
2186
  bzero(tmp1+i, (len1-i)*sizeof(dec1));
2360
2187
 
2361
2188
  start1=tmp1;
2362
2189
  stop1=start1+len1;
2363
2190
  start2=buf2;
2364
 
  stop2=buf2+round_up(prec2)-1;
 
2191
  stop2=buf2+ROUND_UP(prec2)-1;
2365
2192
 
2366
2193
  /* removing end zeroes */
2367
2194
  while (*stop2 == 0 && stop2 >= start2)
2407
2234
          guess--;
2408
2235
        if (unlikely(start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y))
2409
2236
          guess--;
2410
 
        assert(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
 
2237
        DBUG_ASSERT(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
2411
2238
      }
2412
2239
 
2413
2240
      /* D4: multiply and subtract */
2414
2241
      buf2=stop2;
2415
2242
      buf1=start1+len2;
2416
 
      assert(buf1 < stop1);
 
2243
      DBUG_ASSERT(buf1 < stop1);
2417
2244
      for (carry=0; buf2 > start2; buf1--)
2418
2245
      {
2419
2246
        dec1 hi, lo;
2420
2247
        x=guess * (*--buf2);
2421
2248
        hi=(dec1)(x/DIG_BASE);
2422
2249
        lo=(dec1)(x-((dec2)hi)*DIG_BASE);
2423
 
        sub2(*buf1, *buf1, lo, carry);
 
2250
        SUB2(*buf1, *buf1, lo, carry);
2424
2251
        carry+=hi;
2425
2252
      }
2426
2253
      carry= dcarry < carry;
2434
2261
        buf1=start1+len2;
2435
2262
        for (carry=0; buf2 > start2; buf1--)
2436
2263
        {
2437
 
          add(*buf1, *buf1, *--buf2, carry);
 
2264
          ADD(*buf1, *buf1, *--buf2, carry);
2438
2265
        }
2439
2266
      }
2440
2267
    }
2448
2275
    /*
2449
2276
      now the result is in tmp1, it has
2450
2277
        intg=prec1-frac1
2451
 
        frac=cmax(frac1, frac2)=to->frac
 
2278
        frac=max(frac1, frac2)=to->frac
2452
2279
    */
2453
2280
    if (dcarry)
2454
2281
      *--start1=dcarry;
2455
2282
    buf0=to->buf;
2456
 
    intg0=(int) (round_up(prec1-frac1)-(start1-tmp1));
2457
 
    frac0=round_up(to->frac);
 
2283
    intg0=(int) (ROUND_UP(prec1-frac1)-(start1-tmp1));
 
2284
    frac0=ROUND_UP(to->frac);
2458
2285
    error=E_DEC_OK;
2459
2286
    if (unlikely(frac0==0 && intg0==0))
2460
2287
    {
2461
 
      to->set_zero();
 
2288
      decimal_make_zero(to);
2462
2289
      goto done;
2463
2290
    }
2464
2291
    if (intg0<=0)
2465
2292
    {
2466
2293
      if (unlikely(-intg0 >= to->len))
2467
2294
      {
2468
 
        to->set_zero();
 
2295
        decimal_make_zero(to);
2469
2296
        error=E_DEC_TRUNCATED;
2470
2297
        goto done;
2471
2298
      }
2484
2311
        error=E_DEC_OVERFLOW;
2485
2312
        goto done;
2486
2313
      }
2487
 
      assert(intg0 <= round_up(from2->intg));
 
2314
      DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
2488
2315
      stop1=start1+frac0+intg0;
2489
2316
      to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
2490
2317
    }
2495
2322
      to->frac=frac0*DIG_PER_DEC1;
2496
2323
        error=E_DEC_TRUNCATED;
2497
2324
    }
2498
 
    assert(buf0 + (stop1 - start1) <= to->buf + to->len);
 
2325
    DBUG_ASSERT(buf0 + (stop1 - start1) <= to->buf + to->len);
2499
2326
    while (start1 < stop1)
2500
2327
        *buf0++=*start1++;
2501
2328
  }
2502
2329
done:
 
2330
  my_afree(tmp1);
2503
2331
  return error;
2504
2332
}
2505
2333
 
2506
 
/**
2507
 
 @brief  division of two decimals
2508
 
 
2509
 
 @param[in]  from1   dividend
2510
 
 @param[in]  from2   divisor
2511
 
 @param[out] to      quotient
2512
 
 
2513
 
 @return
 
2334
/*
 
2335
  division of two decimals
 
2336
 
 
2337
  SYNOPSIS
 
2338
    decimal_div()
 
2339
      from1   - dividend
 
2340
      from2   - divisor
 
2341
      to      - quotient
 
2342
 
 
2343
  RETURN VALUE
2514
2344
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2515
2345
 
2516
 
 @note
 
2346
  NOTES
2517
2347
    see do_div_mod()
2518
2348
*/
 
2349
 
2519
2350
int
2520
 
decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
 
2351
decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to, int scale_incr)
2521
2352
{
2522
2353
  return do_div_mod(from1, from2, to, 0, scale_incr);
2523
2354
}
2524
2355
 
2525
 
/**
2526
 
 @brief modulus
2527
 
 
2528
 
 the modulus R in    R = M mod N
2529
 
 
2530
 
 is defined as
2531
 
 
2532
 
 0 <= |R| < |M|
2533
 
 sign R == sign M
2534
 
 R = M - k*N, where k is integer
2535
 
 
2536
 
 thus, there's no requirement for M or N to be integers
2537
 
 
2538
 
 
2539
 
 @param from1   dividend
2540
 
 @param from2   divisor
2541
 
 @param to      modulus
2542
 
 
2543
 
 @return
 
2356
/*
 
2357
  modulus
 
2358
 
 
2359
  SYNOPSIS
 
2360
    decimal_mod()
 
2361
      from1   - dividend
 
2362
      from2   - divisor
 
2363
      to      - modulus
 
2364
 
 
2365
  RETURN VALUE
2544
2366
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2545
2367
 
2546
 
 @note
 
2368
  NOTES
2547
2369
    see do_div_mod()
2548
2370
 
 
2371
  DESCRIPTION
 
2372
    the modulus R in    R = M mod N
 
2373
 
 
2374
   is defined as
 
2375
 
 
2376
     0 <= |R| < |M|
 
2377
     sign R == sign M
 
2378
     R = M - k*N, where k is integer
 
2379
 
 
2380
   thus, there's no requirement for M or N to be integers
2549
2381
*/
2550
 
int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
2382
 
 
2383
int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to)
2551
2384
{
2552
2385
  return do_div_mod(from1, from2, 0, to, 0);
2553
2386
}
2554
2387
 
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
 
} /* namespace drizzled */
2569
 
 
2570
2388
#ifdef MAIN
2571
2389
 
2572
2390
int full= 0;
2577
2395
{
2578
2396
  int i;
2579
2397
  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++)
 
2398
  for (i=0; i < ROUND_UP(d->frac)+ROUND_UP(d->intg)-1; i++)
2581
2399
    printf("%09d, ", d->buf[i]);
2582
2400
  printf("%09d} */ ", d->buf[i]);
2583
2401
}
2649
2467
{
2650
2468
  char s1[100], *end;
2651
2469
  int res;
2652
 
  snprintf(s1, sizeof(s1), "'%s'", s);
 
2470
  sprintf(s1, "'%s'", s);
2653
2471
  end= strend(s);
2654
2472
  printf("len=%2d %-30s => res=%d    ", a.len, s1,
2655
2473
         (res= string2decimal(s, &a, &end)));
2663
2481
  double x;
2664
2482
  int res;
2665
2483
 
2666
 
  snprintf(s1, sizeof(s1), "'%s'", s);
 
2484
  sprintf(s1, "'%s'", s);
2667
2485
  end= strend(s);
2668
2486
  string2decimal(s, &a, &end);
2669
2487
  res=decimal2double(&a, &x);
2677
2495
  char s1[100], buf[100], *end;
2678
2496
  int res, i, size=decimal_bin_size(p, s);
2679
2497
 
2680
 
  snprintf(s1, sizeof(s1), "'%s'", str);
 
2498
  sprintf(s1, "'%s'", str);
2681
2499
  end= strend(str);
2682
2500
  string2decimal(str, &a, &end);
2683
2501
  res=decimal2bin(&a, buf, p, s);
2686
2504
  {
2687
2505
    printf("0x");
2688
2506
    for (i=0; i < size; i++)
2689
 
      printf("%02x", ((unsigned char *)buf)[i]);
 
2507
      printf("%02x", ((uchar *)buf)[i]);
2690
2508
  }
2691
2509
  res=bin2decimal(buf, &a, p, s);
2692
2510
  printf(" => res=%d ", res);
2710
2528
  int res;
2711
2529
 
2712
2530
  res=uint64_t2decimal(from, &a);
2713
 
  internal::int64_t10_to_str(from,s,10);
 
2531
  int64_t10_to_str(from,s,10);
2714
2532
  printf("%-40s => res=%d    ", s, res);
2715
2533
  print_decimal(&a, orig, res, ex);
2716
2534
  printf("\n");
2722
2540
  int res;
2723
2541
 
2724
2542
  res=int64_t2decimal(from, &a);
2725
 
  internal::int64_t10_to_str(from,s,-10);
 
2543
  int64_t10_to_str(from,s,-10);
2726
2544
  printf("%-40s => res=%d    ", s, res);
2727
2545
  print_decimal(&a, orig, res, ex);
2728
2546
  printf("\n");
2738
2556
  string2decimal(s, &a, &end);
2739
2557
  res=decimal2uint64_t(&a, &x);
2740
2558
  if (full) dump_decimal(&a);
2741
 
  internal::int64_t10_to_str(x,s1,10);
 
2559
  int64_t10_to_str(x,s1,10);
2742
2560
  printf("%-40s => res=%d    %s\n", s, res, s1);
2743
2561
  check_result_code(res, ex);
2744
2562
  if (orig && strcmp(orig, s1))
2758
2576
  string2decimal(s, &a, &end);
2759
2577
  res=decimal2int64_t(&a, &x);
2760
2578
  if (full) dump_decimal(&a);
2761
 
  internal::int64_t10_to_str(x,s1,-10);
 
2579
  int64_t10_to_str(x,s1,-10);
2762
2580
  printf("%-40s => res=%d    %s\n", s, res, s1);
2763
2581
  check_result_code(res, ex);
2764
2582
  if (orig && strcmp(orig, s1))
2772
2590
{
2773
2591
  char s[100], *end;
2774
2592
  int res;
2775
 
  snprintf(s, sizeof(s), "'%s' + '%s'", s1, s2);
 
2593
  sprintf(s, "'%s' + '%s'", s1, s2);
2776
2594
  end= strend(s1);
2777
2595
  string2decimal(s1, &a, &end);
2778
2596
  end= strend(s2);
2787
2605
{
2788
2606
  char s[100], *end;
2789
2607
  int res;
2790
 
  snprintf(s, sizeof(s), "'%s' - '%s'", s1, s2);
 
2608
  sprintf(s, "'%s' - '%s'", s1, s2);
2791
2609
  end= strend(s1);
2792
2610
  string2decimal(s1, &a, &end);
2793
2611
  end= strend(s2);
2802
2620
{
2803
2621
  char s[100], *end;
2804
2622
  int res;
2805
 
  snprintf(s, sizeof(s), "'%s' <=> '%s'", s1, s2);
 
2623
  sprintf(s, "'%s' <=> '%s'", s1, s2);
2806
2624
  end= strend(s1);
2807
2625
  string2decimal(s1, &a, &end);
2808
2626
  end= strend(s2);
2820
2638
{
2821
2639
  char s[100], *end;
2822
2640
  int res;
2823
 
  snprintf(s, sizeof(s), "'%s' * '%s'", s1, s2);
 
2641
  sprintf(s, "'%s' * '%s'", s1, s2);
2824
2642
  end= strend(s1);
2825
2643
  string2decimal(s1, &a, &end);
2826
2644
  end= strend(s2);
2835
2653
{
2836
2654
  char s[100], *end;
2837
2655
  int res;
2838
 
  snprintf(s, sizeof(s), "'%s' / '%s'", s1, s2);
 
2656
  sprintf(s, "'%s' / '%s'", s1, s2);
2839
2657
  end= strend(s1);
2840
2658
  string2decimal(s1, &a, &end);
2841
2659
  end= strend(s2);
2854
2672
{
2855
2673
  char s[100], *end;
2856
2674
  int res;
2857
 
  snprintf(s, sizeof(s), "'%s' %% '%s'", s1, s2);
 
2675
  sprintf(s, "'%s' %% '%s'", s1, s2);
2858
2676
  end= strend(s1);
2859
2677
  string2decimal(s1, &a, &end);
2860
2678
  end= strend(s2);
2877
2695
{
2878
2696
  char s[100], *end;
2879
2697
  int res;
2880
 
  snprintf(s, sizeof(s), "'%s', %d, %s", s1, n, round_mode[mode]);
 
2698
  sprintf(s, "'%s', %d, %s", s1, n, round_mode[mode]);
2881
2699
  end= strend(s1);
2882
2700
  string2decimal(s1, &a, &end);
2883
2701
  res=decimal_round(&a, &b, n, mode);
2890
2708
void test_mx(int precision, int frac, const char *orig)
2891
2709
{
2892
2710
  char s[100];
2893
 
  snprintf(s, sizeof(s), "%d, %d", precision, frac);
 
2711
  sprintf(s, "%d, %d", precision, frac);
2894
2712
  max_decimal(precision, frac, &a);
2895
2713
  printf("%-40s =>          ", s);
2896
2714
  print_decimal(&a, orig, 0, 0);
2906
2724
  int slen= sizeof(s2);
2907
2725
  int res;
2908
2726
 
2909
 
  snprintf(s, sizeof(s), filler ? "'%s', %d, %d, '%c'" : "'%s', %d, %d, '\\0'",
 
2727
  sprintf(s, filler ? "'%s', %d, %d, '%c'" : "'%s', %d, %d, '\\0'",
2910
2728
          s1, prec, dec, filler);
2911
2729
  end= strend(s1);
2912
2730
  string2decimal(s1, &a, &end);
2926
2744
{
2927
2745
  char s[100], *end;
2928
2746
  int res;
2929
 
  snprintf(s, sizeof(s), "'%s' %s %d", s1, ((shift < 0) ? ">>" : "<<"), abs(shift));
 
2747
  sprintf(s, "'%s' %s %d", s1, ((shift < 0) ? ">>" : "<<"), abs(shift));
2930
2748
  end= strend(s1);
2931
2749
  string2decimal(s1, &a, &end);
2932
2750
  res= decimal_shift(&a, shift);
2939
2757
void test_fr(const char *s1, const char *orig)
2940
2758
{
2941
2759
  char s[100], *end;
2942
 
  snprintf(s, sizeof(s), "'%s'", s1);
 
2760
  sprintf(s, "'%s'", s1);
2943
2761
  printf("%-40s =>          ", s);
2944
2762
  end= strend(s1);
2945
2763
  string2decimal(s1, &a, &end);
3298
3116
 
3299
3117
  return 0;
3300
3118
}
3301
 
 
3302
3119
#endif