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