MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
decimal-t.cc
1 /* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 /*
17  NOTE: This is a more-or-less direct port of the main() program
18  in strings/decimal.c to a Google Test.
19  */
20 
21 #include "my_config.h"
22 #include <gtest/gtest.h>
23 
24 #include <my_global.h>
25 #include <m_string.h>
26 
27 extern "C" {
28 #include <decimal.h>
29 int decimal_shift(decimal_t *dec, int shift);
30 }
31 
32 
33 namespace decimal_unittest {
34 
35 #define DIG_PER_DEC1 9
36 #define DIG_BASE 1000000000
37 #define ROUND_UP(X) (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
38 typedef decimal_digit_t dec1;
39 
40 int full= 0;
41 decimal_t a, b, c;
42 decimal_digit_t buf1[50], buf2[50], buf3[50];
43 
44 void dump_decimal(decimal_t *d)
45 {
46  int i;
47  printf("/* intg=%d, frac=%d, sign=%d, buf[]={", d->intg, d->frac, d->sign);
48  for (i=0; i < ROUND_UP(d->frac)+ROUND_UP(d->intg)-1; i++)
49  printf("%09d, ", d->buf[i]);
50  printf("%09d} */ ", d->buf[i]);
51 }
52 
53 /*
54  The purpose of all these define wrappers is to get a "call stack"
55  whenever some EXPECT_XX generates a failure. A sample error message:
56 
57  # .../unittest/gunit/decimal-t.cc:134: FailureValue of: s
58  # Actual: "0"
59  # Expected: orig
60  # Which is: "1000000000"
61  # arguments were: '999999999', -9, HALF_UP
62  # Google Test trace:
63  # .../unittest/gunit/decimal-t.cc:387:
64  # .../unittest/gunit/decimal-t.cc:686:
65  */
66 
67 #define check_result_code(p1, p2) \
68  { SCOPED_TRACE(""); do_check_result_code(p1, p2); }
69 
70 #define print_decimal(p1, p2, p3, p4, p5) \
71  { SCOPED_TRACE(""); do_print_decimal(p1, p2, p3, p4, p5); }
72 
73 #define test_s2d(p1, p2, p3) \
74  { SCOPED_TRACE(""); do_test_s2d(p1, p2, p3); }
75 
76 #define test_d2f(p1, p2) \
77  { SCOPED_TRACE(""); do_test_d2f(p1, p2); }
78 
79 #define test_d2b2d(p1, p2, p3, p4, p5) \
80  { SCOPED_TRACE(""); do_test_d2b2d(p1, p2, p3, p4, p5); }
81 
82 #define test_f2d(p1, p2) \
83  { SCOPED_TRACE(""); do_test_f2d(p1, p2); }
84 
85 #define test_ull2d(p1, p2, p3) \
86  { SCOPED_TRACE(""); do_test_ull2d(p1, p2, p3); }
87 
88 #define test_ll2d(p1, p2, p3) \
89  { SCOPED_TRACE(""); do_test_ll2d(p1, p2, p3); }
90 
91 #define test_d2ull(p1, p2, p3) \
92  { SCOPED_TRACE(""); do_test_d2ull(p1, p2, p3); }
93 
94 #define test_d2ll(p1, p2, p3) \
95  { SCOPED_TRACE(""); do_test_d2ll(p1, p2, p3); }
96 
97 #define test_da(p1, p2, p3, p4) \
98  { SCOPED_TRACE(""); do_test_da(p1, p2, p3, p4); }
99 
100 #define test_ds(p1, p2, p3, p4) \
101  { SCOPED_TRACE(""); do_test_ds(p1, p2, p3, p4); }
102 
103 #define test_dc(p1, p2, p3) \
104  { SCOPED_TRACE(""); do_test_dc(p1, p2, p3); }
105 
106 #define test_dm(p1, p2, p3, p4) \
107  { SCOPED_TRACE(""); do_test_dm(p1, p2, p3, p4); }
108 
109 #define test_dv(p1, p2, p3, p4) \
110  { SCOPED_TRACE(""); do_test_dv(p1, p2, p3, p4); }
111 
112 #define test_md(p1, p2, p3, p4) \
113  { SCOPED_TRACE(""); do_test_md(p1, p2, p3, p4); }
114 
115 #define test_ro(p1, p2, p3, p4, p5) \
116  { SCOPED_TRACE(""); do_test_ro(p1, p2, p3, p4, p5); }
117 
118 #define test_format(p1, p2, p3, p4, p5) \
119  { SCOPED_TRACE(""); do_test_format(p1, p2, p3, p4, p5); }
120 
121 #define test_mx(p1, p2, p3) \
122  { SCOPED_TRACE(""); do_test_mx(p1, p2, p3); }
123 
124 #define test_pr(p1, p2, p3, p4, p5, p6) \
125  { SCOPED_TRACE(""); do_test_pr(p1, p2, p3, p4, p5, p6); }
126 
127 #define test_sh(p1, p2, p3, p4) \
128  { SCOPED_TRACE(""); do_test_sh(p1, p2, p3, p4); }
129 
130 #define test_fr(p1, p2) \
131  { SCOPED_TRACE(""); do_test_fr(p1, p2); }
132 
133 
134 void do_check_result_code(int actual, int want)
135 {
136  EXPECT_EQ(want, actual);
137 }
138 
139 void do_print_decimal(decimal_t *d, const char *orig, int actual, int want,
140  const char *msg)
141 {
142  char s[100];
143  int slen=sizeof(s);
144 
145  if (full) dump_decimal(d);
146  decimal2string(d, s, &slen, 0, 0, 0);
147  check_result_code(actual, want);
148  if (orig)
149  {
150  EXPECT_STREQ(orig, s) << " arguments were: " << msg;
151  }
152 }
153 
154 void test_d2s()
155 {
156  char s[100];
157  int slen, res;
158 
159  /***********************************/
160  printf("==== decimal2string ====\n");
161  a.buf[0]=12345; a.intg=5; a.frac=0; a.sign=0;
162  slen=sizeof(s);
163  res=decimal2string(&a, s, &slen, 0, 0, 0);
164  dump_decimal(&a); printf(" --> res=%d str='%s' len=%d\n", res, s, slen);
165 
166  a.buf[1]=987000000; a.frac=3;
167  slen=sizeof(s);
168  res=decimal2string(&a, s, &slen, 0, 0, 0);
169  dump_decimal(&a); printf(" --> res=%d str='%s' len=%d\n", res, s, slen);
170 
171  a.sign=1;
172  slen=sizeof(s);
173  res=decimal2string(&a, s, &slen, 0, 0, 0);
174  dump_decimal(&a); printf(" --> res=%d str='%s' len=%d\n", res, s, slen);
175 
176  slen=8;
177  res=decimal2string(&a, s, &slen, 0, 0, 0);
178  dump_decimal(&a); printf(" --> res=%d str='%s' len=%d\n", res, s, slen);
179 
180  slen=5;
181  res=decimal2string(&a, s, &slen, 0, 0, 0);
182  dump_decimal(&a); printf(" --> res=%d str='%s' len=%d\n", res, s, slen);
183 
184  a.buf[0]=987000000; a.frac=3; a.intg=0;
185  slen=sizeof(s);
186  res=decimal2string(&a, s, &slen, 0, 0, 0);
187  dump_decimal(&a); printf(" --> res=%d str='%s' len=%d\n", res, s, slen);
188 }
189 
190 void do_test_s2d(const char *s, const char *orig, int ex)
191 {
192  char s1[100], *end;
193  int res;
194  sprintf(s1, "'%s'", s);
195  end= strend(s);
196  res= string2decimal(s, &a, &end);
197  print_decimal(&a, orig, res, ex, s1);
198 }
199 
200 void do_test_d2f(const char *s, int ex)
201 {
202  char s1[100], *end;
203  double x;
204  int res;
205 
206  sprintf(s1, "'%s'", s);
207  end= strend(s);
208  string2decimal(s, &a, &end);
209  res=decimal2double(&a, &x);
210  if (full) dump_decimal(&a);
211  check_result_code(res, ex);
212 }
213 
214 void do_test_d2b2d(const char *str, int p, int s, const char *orig, int ex)
215 {
216  char s1[100];
217  char s2[100];
218  uchar buf[100];
219  char *end;
220  int res, i, size=decimal_bin_size(p, s);
221 
222  sprintf(s1, "'%s'", str);
223  end= strend(str);
224  string2decimal(str, &a, &end);
225  res=decimal2bin(&a, buf, p, s);
226  sprintf(s2, "%-31s {%2d, %2d} => res=%d size=%-2d ", s1, p, s, res, size);
227  if (full)
228  {
229  printf("0x");
230  for (i=0; i < size; i++)
231  printf("%02x", ((uchar *)buf)[i]);
232  }
233  res=bin2decimal(buf, &a, p, s);
234  print_decimal(&a, orig, res, ex, s2);
235 }
236 
237 void do_test_f2d(double from, int ex)
238 {
239  int res;
240  char s1[100];
241 
242  res=double2decimal(from, &a);
243  sprintf(s1, "%-40.*f => res=%d ", DBL_DIG-2, from, res);
244  print_decimal(&a, 0, res, ex, s1);
245 }
246 
247 void do_test_ull2d(ulonglong from, const char *orig, int ex)
248 {
249  char s[100];
250  char s1[100];
251  int res;
252 
253  res=ulonglong2decimal(from, &a);
254  longlong10_to_str(from,s,10);
255  sprintf(s1, "%-40s => res=%d ", s, res);
256  print_decimal(&a, orig, res, ex, s1);
257 }
258 
259 void do_test_ll2d(longlong from, const char *orig, int ex)
260 {
261  char s[100];
262  char s1[100];
263  int res;
264 
265  res=longlong2decimal(from, &a);
266  longlong10_to_str(from,s,-10);
267  sprintf(s1, "%-40s => res=%d ", s, res);
268  print_decimal(&a, orig, res, ex, s1);
269 }
270 
271 void do_test_d2ull(const char *s, const char *orig, int ex)
272 {
273  char s1[100], *end;
274  char s2[100];
275  ulonglong x;
276  int res;
277 
278  end= strend(s);
279  string2decimal(s, &a, &end);
280  res=decimal2ulonglong(&a, &x);
281  if (full) dump_decimal(&a);
282  longlong10_to_str(x,s1,10);
283  sprintf(s2, "%-40s => res=%d %s\n", s, res, s1);
284  check_result_code(res, ex);
285  if (orig)
286  {
287  EXPECT_STREQ(orig, s1) << " arguments were: " << s2;
288  }
289 }
290 
291 void do_test_d2ll(const char *s, const char *orig, int ex)
292 {
293  char s1[100], *end;
294  char s2[100];
295  longlong x;
296  int res;
297 
298  end= strend(s);
299  string2decimal(s, &a, &end);
300  res=decimal2longlong(&a, &x);
301  if (full) dump_decimal(&a);
302  longlong10_to_str(x,s1,-10);
303  sprintf(s2, "%-40s => res=%d %s\n", s, res, s1);
304  check_result_code(res, ex);
305  if (orig)
306  {
307  EXPECT_STREQ(orig, s1) << " arguments were: " << s2;
308  }
309 }
310 
311 void do_test_da(const char *s1, const char *s2, const char *orig, int ex)
312 {
313  char s[100], *end;
314  int res;
315  sprintf(s, "'%s' + '%s'", s1, s2);
316  end= strend(s1);
317  string2decimal(s1, &a, &end);
318  end= strend(s2);
319  string2decimal(s2, &b, &end);
320  res=decimal_add(&a, &b, &c);
321  print_decimal(&c, orig, res, ex, s);
322 }
323 
324 void do_test_ds(const char *s1, const char *s2, const char *orig, int ex)
325 {
326  char s[100], *end;
327  int res;
328  sprintf(s, "'%s' - '%s'", s1, s2);
329  end= strend(s1);
330  string2decimal(s1, &a, &end);
331  end= strend(s2);
332  string2decimal(s2, &b, &end);
333  res=decimal_sub(&a, &b, &c);
334  print_decimal(&c, orig, res, ex, s);
335 }
336 
337 void do_test_dc(const char *s1, const char *s2, int orig)
338 {
339  char s[100], *end;
340  int res;
341  sprintf(s, "'%s' <=> '%s'", s1, s2);
342  end= strend(s1);
343  string2decimal(s1, &a, &end);
344  end= strend(s2);
345  string2decimal(s2, &b, &end);
346  res=decimal_cmp(&a, &b);
347  EXPECT_EQ(orig, res) << " arguments were: " << s;
348 }
349 
350 void do_test_dm(const char *s1, const char *s2, const char *orig, int ex)
351 {
352  char s[100], *end;
353  int res;
354  sprintf(s, "'%s' * '%s'", s1, s2);
355  end= strend(s1);
356  string2decimal(s1, &a, &end);
357  end= strend(s2);
358  string2decimal(s2, &b, &end);
359  res=decimal_mul(&a, &b, &c);
360  print_decimal(&c, orig, res, ex, s);
361 }
362 
363 void do_test_dv(const char *s1, const char *s2, const char *orig, int ex)
364 {
365  char s[100], *end;
366  int res;
367  sprintf(s, "'%s' / '%s'", s1, s2);
368  end= strend(s1);
369  string2decimal(s1, &a, &end);
370  end= strend(s2);
371  string2decimal(s2, &b, &end);
372  res=decimal_div(&a, &b, &c, 5);
373  check_result_code(res, ex);
374  if (res != E_DEC_DIV_ZERO)
375  print_decimal(&c, orig, res, ex, s);
376 }
377 
378 void do_test_md(const char *s1, const char *s2, const char *orig, int ex)
379 {
380  char s[100], *end;
381  int res;
382  sprintf(s, "'%s' %% '%s'", s1, s2);
383  end= strend(s1);
384  string2decimal(s1, &a, &end);
385  end= strend(s2);
386  string2decimal(s2, &b, &end);
387  res=decimal_mod(&a, &b, &c);
388  check_result_code(res, ex);
389  if (res != E_DEC_DIV_ZERO)
390  print_decimal(&c, orig, res, ex, s);
391 }
392 
393 const char *round_mode[]=
394 {"TRUNCATE", "HALF_EVEN", "HALF_UP", "CEILING", "FLOOR"};
395 
396 void do_test_ro(const char *s1, int n, decimal_round_mode mode,
397  const char *orig, int ex)
398 {
399  char s[100], *end;
400  int res;
401  sprintf(s, "'%s', %d, %s", s1, n, round_mode[mode]);
402  end= strend(s1);
403  string2decimal(s1, &a, &end);
404  res=decimal_round(&a, &b, n, mode);
405  print_decimal(&b, orig, res, ex, s);
406 }
407 
408 
409 void do_test_format(const char *s1, const char *s2, int n, const char *orig,
410  int ex)
411 {
412  char s[200], *end;
413  decimal_t a,b,c,d;
414  decimal_digit_t buf1[9],buf2[9],buf3[9],buf4[9];
415  int res;
416  a.buf= buf1;
417  b.buf= buf2;
418  c.buf= buf3;
419  d.buf= buf4;
420  a.len= sizeof(buf1)/sizeof(dec1);
421  b.len= sizeof(buf2)/sizeof(dec1);
422  c.len= sizeof(buf3)/sizeof(dec1);
423  d.len= sizeof(buf4)/sizeof(dec1);
424 
425  sprintf(s, "'%s' %% '%s'", s1, s2);
426  end= strend(s1);
427  string2decimal(s1, &a, &end);
428  end= strend(s2);
429  string2decimal(s2, &b, &end);
430  decimal_mod(&a, &b, &c);
431  res=decimal_round(&c, &d, n, HALF_UP);
432  print_decimal(&d, orig, res, ex, s);
433 
434 }
435 void do_test_mx(int precision, int frac, const char *orig)
436 {
437  char s[100];
438  sprintf(s, "%d, %d", precision, frac);
439  max_decimal(precision, frac, &a);
440  print_decimal(&a, orig, 0, 0, s);
441 }
442 
443 
444 void do_test_pr(const char *s1, int prec, int dec, char filler,
445  const char *orig, int ex)
446 {
447  char s[100], *end;
448  char s2[100];
449  int slen= sizeof(s2);
450  int res;
451 
452  if (filler)
453  sprintf(s, "'%s', %d, %d, '%c'", s1, prec, dec, filler);
454  else
455  sprintf(s, "'%s', %d, %d, '\\0'", s1, prec, dec);
456  end= strend(s1);
457  string2decimal(s1, &a, &end);
458  res= decimal2string(&a, s2, &slen, prec, dec, filler);
459  check_result_code(res, ex);
460  if (orig)
461  {
462  EXPECT_STREQ(orig, s2) << " arguments were: " << s;
463  }
464 }
465 
466 
467 void do_test_sh(const char *s1, int shift, const char *orig, int ex)
468 {
469  char s[100], *end;
470  int res;
471  sprintf(s, "'%s' %s %d", s1, ((shift < 0) ? ">>" : "<<"), abs(shift));
472  end= strend(s1);
473  string2decimal(s1, &a, &end);
474  res= decimal_shift(&a, shift);
475  print_decimal(&a, orig, res, ex, s);
476 }
477 
478 
479 void do_test_fr(const char *s1, const char *orig)
480 {
481  char s[100], *end;
482  sprintf(s, "'%s'", s1);
483  end= strend(s1);
484  string2decimal(s1, &a, &end);
485  a.frac= decimal_actual_fraction(&a);
486  print_decimal(&a, orig, 0, 0, s);
487 }
488 
489 
490 class DecimalTest : public ::testing::Test
491 {
492 protected:
493  virtual void SetUp()
494  {
495  a.buf= buf1;
496  a.len= sizeof(buf1)/sizeof(dec1);
497  b.buf= buf2;
498  b.len= sizeof(buf2)/sizeof(dec1);
499  c.buf= buf3;
500  c.len= sizeof(buf3)/sizeof(dec1);
501  }
502 };
503 
504 
505 TEST_F(DecimalTest, String2Decimal)
506 {
507  test_s2d("12345", "12345", 0);
508  test_s2d("12345.", "12345", 0);
509  test_s2d("123.45", "123.45", 0);
510  test_s2d("-123.45", "-123.45", 0);
511  test_s2d(".00012345000098765", "0.00012345000098765", 0);
512  test_s2d(".12345000098765", "0.12345000098765", 0);
513  test_s2d("-.000000012345000098765", "-0.000000012345000098765", 0);
514  test_s2d("1234500009876.5", "1234500009876.5", 0);
515  a.len=1;
516  test_s2d("123450000098765", "98765", 2);
517  test_s2d("123450.000098765", "123450", 1);
518  a.len=sizeof(buf1)/sizeof(dec1);
519  test_s2d("123E5", "12300000", 0);
520  test_s2d("123E-2", "1.23", 0);
521 }
522 
523 
524 TEST_F(DecimalTest, Decimal2Double)
525 {
526  test_d2f("12345", 0);
527  test_d2f("123.45", 0);
528  test_d2f("-123.45", 0);
529  test_d2f("0.00012345000098765", 0);
530  test_d2f("1234500009876.5", 0);
531 }
532 
533 
534 TEST_F(DecimalTest, Double2Decimal)
535 {
536  test_f2d(12345, 0);
537  test_f2d(1.0/3, 0);
538  test_f2d(-123.45, 0);
539  test_f2d(0.00012345000098765, 0);
540  test_f2d(1234500009876.5, 0);
541 }
542 
543 
544 TEST_F(DecimalTest, Ulonglong2Decimal)
545 {
546  test_ull2d(ULL(12345), "12345", 0);
547  test_ull2d(ULL(0), "0", 0);
548  test_ull2d(ULL(18446744073709551615), "18446744073709551615", 0);
549 }
550 
551 
552 TEST_F(DecimalTest, Decimal2Ulonglong)
553 {
554  test_d2ull("12345", "12345", 0);
555  test_d2ull("0", "0", 0);
556  /* ULLONG_MAX = 18446744073709551615ULL */
557  test_d2ull("18446744073709551615", "18446744073709551615", 0);
558  test_d2ull("18446744073709551616", "18446744073709551615", 2);
559  test_d2ull("-1", "0", 2);
560  test_d2ull("1.23", "1", 1);
561  test_d2ull("9999999999999999999999999.000", "18446744073709551615", 2);
562 }
563 
564 
565 TEST_F(DecimalTest, Longlong2Decimal)
566 {
567  test_ll2d(LL(-12345), "-12345", 0);
568  test_ll2d(LL(-1), "-1", 0);
569  test_ll2d(LL(-9223372036854775807), "-9223372036854775807", 0);
570  test_ll2d(ULL(9223372036854775808), "-9223372036854775808", 0);
571 }
572 
573 
574 TEST_F(DecimalTest, Decimal2Longlong)
575 {
576  /* LLONG_MAX = 9223372036854775807LL */
577  test_d2ll("18446744073709551615", "9223372036854775807", 2);
578  test_d2ll("-1", "-1", 0);
579  test_d2ll("-1.23", "-1", 1);
580  test_d2ll("-9223372036854775807", "-9223372036854775807", 0);
581  test_d2ll("-9223372036854775808", "-9223372036854775808", 0);
582  test_d2ll("9223372036854775808", "9223372036854775807", 2);
583 }
584 
585 
586 TEST_F(DecimalTest, DoAdd)
587 {
588  test_da(".00012345000098765" ,"123.45", "123.45012345000098765", 0);
589  test_da(".1" ,".45", "0.55", 0);
590  test_da("1234500009876.5" ,".00012345000098765", "1234500009876.50012345000098765", 0);
591  test_da("9999909999999.5" ,".555", "9999910000000.055", 0);
592  test_da("99999999" ,"1", "100000000", 0);
593  test_da("989999999" ,"1", "990000000", 0);
594  test_da("999999999" ,"1", "1000000000", 0);
595  test_da("12345" ,"123.45", "12468.45", 0);
596  test_da("-12345" ,"-123.45", "-12468.45", 0);
597  test_ds("-12345" ,"123.45", "-12468.45", 0);
598  test_ds("12345" ,"-123.45", "12468.45", 0);
599 }
600 
601 
602 TEST_F(DecimalTest, DoSub)
603 {
604  test_ds(".00012345000098765", "123.45","-123.44987654999901235", 0);
605  test_ds("1234500009876.5", ".00012345000098765","1234500009876.49987654999901235", 0);
606  test_ds("9999900000000.5", ".555","9999899999999.945", 0);
607  test_ds("1111.5551", "1111.555","0.0001", 0);
608  test_ds(".555", ".555","0", 0);
609  test_ds("10000000", "1","9999999", 0);
610  test_ds("1000001000", ".1","1000000999.9", 0);
611  test_ds("1000000000", ".1","999999999.9", 0);
612  test_ds("12345", "123.45","12221.55", 0);
613  test_ds("-12345", "-123.45","-12221.55", 0);
614  test_da("-12345", "123.45","-12221.55", 0);
615  test_da("12345", "-123.45","12221.55", 0);
616  test_ds("123.45", "12345","-12221.55", 0);
617  test_ds("-123.45", "-12345","12221.55", 0);
618  test_da("123.45", "-12345","-12221.55", 0);
619  test_da("-123.45", "12345","12221.55", 0);
620  test_da("5", "-6.0","-1.0", 0);
621 }
622 
623 
624 TEST_F(DecimalTest, DecimalMul)
625 {
626  test_dm("12", "10","120", 0);
627  test_dm("-123.456", "98765.4321","-12193185.1853376", 0);
628  test_dm("-123456000000", "98765432100000","-12193185185337600000000000", 0);
629  test_dm("123456", "987654321","121931851853376", 0);
630  test_dm("123456", "9876543210","1219318518533760", 0);
631  test_dm("123", "0.01","1.23", 0);
632  test_dm("123", "0","0", 0);
633 }
634 
635 
636 TEST_F(DecimalTest, DecimalDiv)
637 {
638  test_dv("120", "10","12.000000000", 0);
639  test_dv("123", "0.01","12300.000000000", 0);
640  test_dv("120", "100000000000.00000","0.000000001200000000", 0);
641  test_dv("123", "0","", 4);
642  test_dv("0", "0", "", 4);
643  test_dv("-12193185.1853376", "98765.4321","-123.456000000000000000", 0);
644  test_dv("121931851853376", "987654321","123456.000000000", 0);
645  test_dv("0", "987","0", 0);
646  test_dv("1", "3","0.333333333", 0);
647  test_dv("1.000000000000", "3","0.333333333333333333", 0);
648  test_dv("1", "1","1.000000000", 0);
649  test_dv("0.0123456789012345678912345", "9999999999","0.000000000001234567890246913578148141", 0);
650  test_dv("10.333000000", "12.34500","0.837019036046982584042122316", 0);
651  test_dv("10.000000000060", "2","5.000000000030000000", 0);
652 }
653 
654 
655 TEST_F(DecimalTest, DecimalMod)
656 {
657  test_md("234","10","4", 0);
658  test_md("234.567","10.555","2.357", 0);
659  test_md("-234.567","10.555","-2.357", 0);
660  test_md("234.567","-10.555","2.357", 0);
661  c.buf[1]=0x3ABECA;
662  test_md("99999999999999999999999999999999999999","3","0", 0);
663  if (c.buf[1] != 0x3ABECA)
664  {
665  ADD_FAILURE() << "overflow " << c.buf[1];
666  }
667 }
668 
669 
670 TEST_F(DecimalTest, Decimal2BinBin2Decimal)
671 {
672  test_d2b2d("-10.55", 4, 2,"-10.55", 0);
673  test_d2b2d("0.0123456789012345678912345", 30, 25,"0.0123456789012345678912345", 0);
674  test_d2b2d("12345", 5, 0,"12345", 0);
675  test_d2b2d("12345", 10, 3,"12345.000", 0);
676  test_d2b2d("123.45", 10, 3,"123.450", 0);
677  test_d2b2d("-123.45", 20, 10,"-123.4500000000", 0);
678  test_d2b2d(".00012345000098765", 15, 14,"0.00012345000098", 0);
679  test_d2b2d(".00012345000098765", 22, 20,"0.00012345000098765000", 0);
680  test_d2b2d(".12345000098765", 30, 20,"0.12345000098765000000", 0);
681  test_d2b2d("-.000000012345000098765", 30, 20,"-0.00000001234500009876", 0);
682  test_d2b2d("1234500009876.5", 30, 5,"1234500009876.50000", 0);
683  test_d2b2d("111111111.11", 10, 2,"11111111.11", 0);
684  test_d2b2d("000000000.01", 7, 3,"0.010", 0);
685  test_d2b2d("123.4", 10, 2, "123.40", 0);
686 }
687 
688 
689 TEST_F(DecimalTest, DecimalCmp)
690 {
691  test_dc("12","13",-1);
692  test_dc("13","12",1);
693  test_dc("-10","10",-1);
694  test_dc("10","-10",1);
695  test_dc("-12","-13",1);
696  test_dc("0","12",-1);
697  test_dc("-10","0",-1);
698  test_dc("4","4",0);
699 }
700 
701 
702 TEST_F(DecimalTest, DecimalRound)
703 {
704  test_ro("5678.123451",-4,TRUNCATE,"0", 0);
705  test_ro("5678.123451",-3,TRUNCATE,"5000", 0);
706  test_ro("5678.123451",-2,TRUNCATE,"5600", 0);
707  test_ro("5678.123451",-1,TRUNCATE,"5670", 0);
708  test_ro("5678.123451",0,TRUNCATE,"5678", 0);
709  test_ro("5678.123451",1,TRUNCATE,"5678.1", 0);
710  test_ro("5678.123451",2,TRUNCATE,"5678.12", 0);
711  test_ro("5678.123451",3,TRUNCATE,"5678.123", 0);
712  test_ro("5678.123451",4,TRUNCATE,"5678.1234", 0);
713  test_ro("5678.123451",5,TRUNCATE,"5678.12345", 0);
714  test_ro("5678.123451",6,TRUNCATE,"5678.123451", 0);
715  test_ro("-5678.123451",-4,TRUNCATE,"0", 0);
716  memset(buf2, 33, sizeof(buf2));
717  test_ro("99999999999999999999999999999999999999",-31,TRUNCATE,"99999990000000000000000000000000000000", 0);
718  test_ro("15.1",0,HALF_UP,"15", 0);
719  test_ro("15.5",0,HALF_UP,"16", 0);
720  test_ro("15.9",0,HALF_UP,"16", 0);
721  test_ro("-15.1",0,HALF_UP,"-15", 0);
722  test_ro("-15.5",0,HALF_UP,"-16", 0);
723  test_ro("-15.9",0,HALF_UP,"-16", 0);
724  test_ro("15.1",1,HALF_UP,"15.1", 0);
725  test_ro("-15.1",1,HALF_UP,"-15.1", 0);
726  test_ro("15.17",1,HALF_UP,"15.2", 0);
727  test_ro("15.4",-1,HALF_UP,"20", 0);
728  test_ro("-15.4",-1,HALF_UP,"-20", 0);
729  test_ro("5.4",-1,HALF_UP,"10", 0);
730  test_ro(".999", 0, HALF_UP, "1", 0);
731  memset(buf2, 33, sizeof(buf2));
732  test_ro("999999999", -9, HALF_UP, "1000000000", 0);
733  test_ro("15.1",0,HALF_EVEN,"15", 0);
734  test_ro("15.5",0,HALF_EVEN,"16", 0);
735  test_ro("14.5",0,HALF_EVEN,"14", 0);
736  test_ro("15.9",0,HALF_EVEN,"16", 0);
737  test_ro("15.1",0,CEILING,"16", 0);
738  test_ro("-15.1",0,CEILING,"-15", 0);
739  test_ro("15.1",0,FLOOR,"15", 0);
740  test_ro("-15.1",0,FLOOR,"-16", 0);
741  test_ro("999999999999999999999.999", 0, CEILING,"1000000000000000000000", 0);
742  test_ro("-999999999999999999999.999", 0, FLOOR,"-1000000000000000000000", 0);
743 
744  b.buf[0]=DIG_BASE+1;
745  b.buf++;
746  test_ro(".3", 0, HALF_UP, "0", 0);
747  b.buf--;
748  if (b.buf[0] != DIG_BASE+1)
749  {
750  ADD_FAILURE() << "underflow " << b.buf[0];
751  }
752 }
753 
754 
755 TEST_F(DecimalTest, FormatFunc)
756 {
757  test_format("999999999999999999999999999999999999999999999999999999999999999",
758  "999999999999999999999999999999999999999999999999999999999999999",
759  42,"0.000000000000000000000000000000000000000000",0);
760 }
761 
762 
763 TEST_F(DecimalTest, MaxDecimal)
764 {
765  test_mx(1,1,"0.9");
766  test_mx(1,0,"9");
767  test_mx(2,1,"9.9");
768  test_mx(4,2,"99.99");
769  test_mx(6,3,"999.999");
770  test_mx(8,4,"9999.9999");
771  test_mx(10,5,"99999.99999");
772  test_mx(12,6,"999999.999999");
773  test_mx(14,7,"9999999.9999999");
774  test_mx(16,8,"99999999.99999999");
775  test_mx(18,9,"999999999.999999999");
776  test_mx(20,10,"9999999999.9999999999");
777  test_mx(20,20,"0.99999999999999999999");
778  test_mx(20,0,"99999999999999999999");
779  test_mx(40,20,"99999999999999999999.99999999999999999999");
780 }
781 
782 
783 TEST_F(DecimalTest, Decimal2String)
784 {
785  test_pr("123.123", 0, 0, 0, "123.123", 0);
786  /* For fixed precision, we no longer count the '.' here. */
787  test_pr("123.123", 6, 3, '0', "123.123", 0);
788  test_pr("123.123", 8, 3, '0', "00123.123", 0);
789  test_pr("123.123", 8, 4, '0', "0123.1230", 0);
790  test_pr("123.123", 8, 5, '0', "123.12300", 0);
791  test_pr("123.123", 8, 2, '0', "000123.12", 1);
792  test_pr("123.123", 8, 6, '0', "23.123000", 2);
793 }
794 
795 
796 TEST_F(DecimalTest, DecimalShift)
797 {
798  test_sh("123.123", 1, "1231.23", 0);
799  test_sh("123457189.123123456789000", 1, "1234571891.23123456789", 0);
800  test_sh("123457189.123123456789000", 4, "1234571891231.23456789", 0);
801  test_sh("123457189.123123456789000", 8, "12345718912312345.6789", 0);
802  test_sh("123457189.123123456789000", 9, "123457189123123456.789", 0);
803  test_sh("123457189.123123456789000", 10, "1234571891231234567.89", 0);
804  test_sh("123457189.123123456789000", 17, "12345718912312345678900000", 0);
805  test_sh("123457189.123123456789000", 18, "123457189123123456789000000", 0);
806  test_sh("123457189.123123456789000", 19, "1234571891231234567890000000", 0);
807  test_sh("123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
808  test_sh("123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
809  test_sh("123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
810  test_sh("000000000000000000000000123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
811  test_sh("00000000123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
812  test_sh("00000000000000000123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
813  test_sh("123", 1, "1230", 0);
814  test_sh("123", 10, "1230000000000", 0);
815  test_sh(".123", 1, "1.23", 0);
816  test_sh(".123", 10, "1230000000", 0);
817  test_sh(".123", 14, "12300000000000", 0);
818  test_sh("000.000", 1000, "0", 0);
819  test_sh("000.", 1000, "0", 0);
820  test_sh(".000", 1000, "0", 0);
821  test_sh("1", 1000, "1", 2);
822  test_sh("123.123", -1, "12.3123", 0);
823  test_sh("123987654321.123456789000", -1, "12398765432.1123456789", 0);
824  test_sh("123987654321.123456789000", -2, "1239876543.21123456789", 0);
825  test_sh("123987654321.123456789000", -3, "123987654.321123456789", 0);
826  test_sh("123987654321.123456789000", -8, "1239.87654321123456789", 0);
827  test_sh("123987654321.123456789000", -9, "123.987654321123456789", 0);
828  test_sh("123987654321.123456789000", -10, "12.3987654321123456789", 0);
829  test_sh("123987654321.123456789000", -11, "1.23987654321123456789", 0);
830  test_sh("123987654321.123456789000", -12, "0.123987654321123456789", 0);
831  test_sh("123987654321.123456789000", -13, "0.0123987654321123456789", 0);
832  test_sh("123987654321.123456789000", -14, "0.00123987654321123456789", 0);
833  test_sh("00000087654321.123456789000", -14, "0.00000087654321123456789", 0);
834  a.len= 2;
835  test_sh("123.123", -2, "1.23123", 0);
836  test_sh("123.123", -3, "0.123123", 0);
837  test_sh("123.123", -6, "0.000123123", 0);
838  test_sh("123.123", -7, "0.0000123123", 0);
839  test_sh("123.123", -15, "0.000000000000123123", 0);
840  test_sh("123.123", -16, "0.000000000000012312", 1);
841  test_sh("123.123", -17, "0.000000000000001231", 1);
842  test_sh("123.123", -18, "0.000000000000000123", 1);
843  test_sh("123.123", -19, "0.000000000000000012", 1);
844  test_sh("123.123", -20, "0.000000000000000001", 1);
845  test_sh("123.123", -21, "0", 1);
846  test_sh(".000000000123", -1, "0.0000000000123", 0);
847  test_sh(".000000000123", -6, "0.000000000000000123", 0);
848  test_sh(".000000000123", -7, "0.000000000000000012", 1);
849  test_sh(".000000000123", -8, "0.000000000000000001", 1);
850  test_sh(".000000000123", -9, "0", 1);
851  test_sh(".000000000123", 1, "0.00000000123", 0);
852  test_sh(".000000000123", 8, "0.0123", 0);
853  test_sh(".000000000123", 9, "0.123", 0);
854  test_sh(".000000000123", 10, "1.23", 0);
855  test_sh(".000000000123", 17, "12300000", 0);
856  test_sh(".000000000123", 18, "123000000", 0);
857  test_sh(".000000000123", 19, "1230000000", 0);
858  test_sh(".000000000123", 20, "12300000000", 0);
859  test_sh(".000000000123", 21, "123000000000", 0);
860  test_sh(".000000000123", 22, "1230000000000", 0);
861  test_sh(".000000000123", 23, "12300000000000", 0);
862  test_sh(".000000000123", 24, "123000000000000", 0);
863  test_sh(".000000000123", 25, "1230000000000000", 0);
864  test_sh(".000000000123", 26, "12300000000000000", 0);
865  test_sh(".000000000123", 27, "123000000000000000", 0);
866  test_sh(".000000000123", 28, "0.000000000123", 2);
867  test_sh("123456789.987654321", -1, "12345678.998765432", 1);
868  test_sh("123456789.987654321", -2, "1234567.899876543", 1);
869  test_sh("123456789.987654321", -8, "1.234567900", 1);
870  test_sh("123456789.987654321", -9, "0.123456789987654321", 0);
871  test_sh("123456789.987654321", -10, "0.012345678998765432", 1);
872  test_sh("123456789.987654321", -17, "0.000000001234567900", 1);
873  test_sh("123456789.987654321", -18, "0.000000000123456790", 1);
874  test_sh("123456789.987654321", -19, "0.000000000012345679", 1);
875  test_sh("123456789.987654321", -26, "0.000000000000000001", 1);
876  test_sh("123456789.987654321", -27, "0", 1);
877  test_sh("123456789.987654321", 1, "1234567900", 1);
878  test_sh("123456789.987654321", 2, "12345678999", 1);
879  test_sh("123456789.987654321", 4, "1234567899877", 1);
880  test_sh("123456789.987654321", 8, "12345678998765432", 1);
881  test_sh("123456789.987654321", 9, "123456789987654321", 0);
882  test_sh("123456789.987654321", 10, "123456789.987654321", 2);
883  test_sh("123456789.987654321", 0, "123456789.987654321", 0);
884  a.len= sizeof(buf1)/sizeof(dec1);
885 }
886 
887 
888 TEST_F(DecimalTest, DecimalActualFraction)
889 {
890  test_fr("1.123456789000000000", "1.123456789");
891  test_fr("1.12345678000000000", "1.12345678");
892  test_fr("1.1234567000000000", "1.1234567");
893  test_fr("1.123456000000000", "1.123456");
894  test_fr("1.12345000000000", "1.12345");
895  test_fr("1.1234000000000", "1.1234");
896  test_fr("1.123000000000", "1.123");
897  test_fr("1.12000000000", "1.12");
898  test_fr("1.1000000000", "1.1");
899  test_fr("1.000000000", "1");
900  test_fr("1.0", "1");
901  test_fr("10000000000000000000.0", "10000000000000000000");
902 }
903 
904 
905 }