109 #include <drizzled/internal/m_string.h>
110 #include <drizzled/charset.h>
111 #include <drizzled/type/decimal.h>
113 #include <plugin/myisam/myisampack.h>
114 #include <drizzled/util/test.h>
122 #include <drizzled/current_session.h>
123 #include <drizzled/error.h>
124 #include <drizzled/field.h>
125 #include <drizzled/internal/my_sys.h>
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),
154 push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
155 ER_TRUNCATED_WRONG_VALUE,
156 ER(ER_TRUNCATED_WRONG_VALUE),
160 my_error(ER_DIVISION_BY_ZERO, MYF(0));
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);
169 my_error(ER_OUT_OF_RESOURCES, MYF(0));
198 uint32_t fixed_dec,
String *str)
200 uint32_t mask= E_DEC_FATAL_ERROR;
214 ? (uint32_t)(((0 == fixed_dec) ? 1 : 0) + 1)
215 : (uint32_t)d->string_length());
220 &length, (int)0, fixed_dec,
223 return check_result(mask, result);
248 int Decimal::val_binary(uint32_t mask,
unsigned char *bin,
int prec,
int scale)
const
250 int err1= E_DEC_OK, err2;
251 type::Decimal rounded;
252 class_decimal2decimal(
this, &rounded);
254 if (scale < rounded.frac)
256 err1= E_DEC_TRUNCATED;
263 return check_result(mask, err2);
285 int type::Decimal::store(uint32_t mask,
const char *from, uint32_t length,
const charset_info_st * charset)
287 char *end, *from_end;
289 char buff[STRING_BUFFER_USUAL_SIZE];
290 String tmp(buff,
sizeof(buff), &my_charset_bin);
291 if (charset->mbminlen > 1)
293 tmp.copy(from, length, &my_charset_utf8_general_ci);
295 length= tmp.length();
296 charset= &my_charset_bin;
298 from_end= end= (
char*) from+length;
299 err= string2decimal((
char *)from, (
decimal_t*)
this, &end);
300 if (end != from_end && !err)
303 for ( ; end < from_end; end++)
305 if (not my_charset_utf8_general_ci.isspace(*end))
307 err= E_DEC_TRUNCATED;
312 check_result_and_overflow(mask, err);
316 void type::Decimal::convert(
double &result)
const
324 date = (ltime->year*100L + ltime->month)*100L + ltime->day;
325 if (ltime->time_type > type::DRIZZLE_TIMESTAMP_DATE)
326 date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
328 if (int2_class_decimal(E_DEC_FATAL_ERROR, date,
false, dec))
331 if (ltime->second_part)
333 dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
341 void class_decimal_trim(uint32_t *precision, uint32_t *scale)
343 if (!(*precision) && !(*scale))
367 typedef decimal_digit_t dec1;
368 typedef int64_t dec2;
370 #define DIG_PER_DEC1 9
371 #define DIG_MASK 100000000
372 #define DIG_BASE 1000000000
373 #define DIG_MAX (DIG_BASE-1)
376 inline static T round_up(
const T &x)
378 return (x+DIG_PER_DEC1-1)/DIG_PER_DEC1;
381 static const dec1 powers10[DIG_PER_DEC1+1]={
382 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
383 static const int dig2bytes[DIG_PER_DEC1+1]={0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
384 static const dec1 frac_max[DIG_PER_DEC1-1]={
385 900000000, 990000000, 999000000,
386 999900000, 999990000, 999999000,
387 999999900, 999999990 };
390 #define sanity(d) assert((d)->len > 0)
392 #define sanity(d) assert((d)->len >0 && ((d)->buf[0] | \
393 (d)->buf[(d)->len-1] | 1))
396 inline static void fix_intg_frac_error(
const int len,
int &intg1,
int &frac1,
int &error)
398 if (unlikely(intg1+frac1 > len))
400 if (unlikely(intg1 > len))
404 error=E_DEC_OVERFLOW;
409 error=E_DEC_TRUNCATED;
417 inline static void add(dec1 &to,
const dec1 &from1,
const dec1& from2, dec1 &carry)
419 dec1 a=from1+from2+carry;
421 if ((carry= (a >= DIG_BASE)))
426 inline static void add2(dec1 &to,
const dec1 &from1,
const dec1 &from2, dec1 &carry)
428 dec2 a=dec2(from1)+from2+carry;
429 if ((carry= (a >= DIG_BASE)))
431 if (unlikely(a >= DIG_BASE))
440 inline static void sub(dec1 &to,
const dec1 &from1,
const dec1 &from2, dec1 &carry)
442 dec1 a=from1-from2-carry;
443 if ((carry= (a < 0)))
449 inline static void sub2(dec1 &to,
const dec1 &from1,
const dec1 &from2, dec1 &carry)
451 dec1 a=from1-from2-carry;
452 if ((carry= (a < 0)))
474 assert(precision && precision >= frac);
477 if ((intpart= to->intg= (precision - frac)))
479 const int firstdigits= intpart % DIG_PER_DEC1;
481 *buf++= powers10[firstdigits] - 1;
482 for(intpart/= DIG_PER_DEC1; intpart; intpart--)
486 if ((to->frac= frac))
488 const int lastdigits= frac % DIG_PER_DEC1;
489 for(frac/= DIG_PER_DEC1; frac; frac--)
492 *buf= frac_max[lastdigits - 1];
497 static dec1 *remove_leading_zeroes(
const decimal_t *from,
int *intg_result)
499 int intg= from->intg, i;
500 dec1 *buf0= from->buf;
501 i= ((intg - 1) % DIG_PER_DEC1) + 1;
502 while (intg > 0 && *buf0 == 0)
510 for (i= (intg - 1) % DIG_PER_DEC1; *buf0 < powers10[i--]; intg--) ;
528 int frac= from->frac, i;
529 dec1 *buf0= from->buf + round_up(from->intg) + round_up(frac) - 1;
534 i= ((frac - 1) % DIG_PER_DEC1 + 1);
535 while (frac > 0 && *buf0 == 0)
543 for (i= DIG_PER_DEC1 - ((frac - 1) % DIG_PER_DEC1); *buf0 % powers10[i++] == 0; frac--) {};
571 int fixed_precision,
int fixed_decimals,
574 int len, intg, frac= from->frac, i, intg_len, frac_len, fill;
576 int fixed_intg= (fixed_precision ?
577 (fixed_precision - fixed_decimals) : 0);
580 dec1 *buf, *buf0=from->buf, tmp;
582 assert(*to_len >= 2+from->sign);
585 buf0= remove_leading_zeroes(from, &intg);
586 if (unlikely(intg+frac==0))
593 if (!(intg_len= fixed_precision ? fixed_intg : intg))
595 frac_len= fixed_precision ? fixed_decimals : frac;
596 len= from->sign + intg_len + test(frac) + frac_len;
599 if (frac > fixed_decimals)
601 error= E_DEC_TRUNCATED;
602 frac= fixed_decimals;
604 if (intg > fixed_intg)
606 error= E_DEC_OVERFLOW;
610 else if (unlikely(len > --*to_len))
613 error= (frac && j <= frac + 1) ? E_DEC_TRUNCATED : E_DEC_OVERFLOW;
614 if (frac && j >= frac + 1) j--;
622 len= from->sign + intg_len + test(frac) + frac_len;
632 char *s1= s + intg_len;
633 fill= frac_len - frac;
634 buf=buf0+round_up(intg);
636 for (; frac>0; frac-=DIG_PER_DEC1)
639 for (i=min(frac, DIG_PER_DEC1); i; i--)
642 *s1++=
'0'+(
unsigned char)y;
651 fill= intg_len - intg;
659 for (buf=buf0+round_up(intg); intg>0; intg-=DIG_PER_DEC1)
662 for (i=min(intg, DIG_PER_DEC1); i; i--)
665 *--s=
'0'+(
unsigned char)(x-y*10);
688 dec1 *buf_beg= from->buf;
689 dec1 *end= from->buf + round_up(from->intg) + round_up(from->frac);
690 dec1 *buf_end= end - 1;
693 while (buf_beg < end && *buf_beg == 0)
699 *start_result= *end_result= 0;
704 if (buf_beg == from->buf && from->intg)
706 start= DIG_PER_DEC1 - (i= ((from->intg-1) % DIG_PER_DEC1 + 1));
712 start= (int) ((buf_beg - from->buf) * DIG_PER_DEC1);
715 for (; *buf_beg < powers10[i--]; start++) ;
716 *start_result= start;
719 while (buf_end > buf_beg && *buf_end == 0)
722 if (buf_end == end - 1 && from->frac)
724 stop= (int) (((buf_end - from->buf) * DIG_PER_DEC1 +
725 (i= ((from->frac - 1) % DIG_PER_DEC1 + 1))));
726 i= DIG_PER_DEC1 - i + 1;
730 stop= (int) ((buf_end - from->buf + 1) * DIG_PER_DEC1);
733 for (; *buf_end % powers10[i++] == 0; stop--) {};
755 dec1 *from= dec->buf + round_up(beg + 1) - 1;
756 dec1 *end= dec->buf + round_up(last) - 1;
757 int c_shift= DIG_PER_DEC1 - shift;
758 assert(from >= dec->buf);
759 assert(end < dec->buf + dec->len);
760 if (beg % DIG_PER_DEC1 < shift)
761 *(from - 1)= (*from) / powers10[c_shift];
762 for(; from < end; from++)
763 *from= ((*from % powers10[c_shift]) * powers10[shift] +
764 (*(from + 1)) / powers10[c_shift]);
765 *from= (*from % powers10[c_shift]) * powers10[shift];
783 dec1 *from= dec->buf + round_up(last) - 1;
784 dec1 *end= dec->buf + round_up(beg + 1) - 1;
785 int c_shift= DIG_PER_DEC1 - shift;
786 assert(from < dec->buf + dec->len);
787 assert(end >= dec->buf);
788 if (DIG_PER_DEC1 - ((last - 1) % DIG_PER_DEC1 + 1) < shift)
789 *(from + 1)= (*from % powers10[shift]) * powers10[c_shift];
790 for(; from > end; from--)
791 *from= (*from / powers10[shift] +
792 (*(from - 1) % powers10[shift]) * powers10[c_shift]);
793 *from= *from / powers10[shift];
820 int point= round_up(dec->intg) * DIG_PER_DEC1;
822 int new_point= point + shift;
824 int digits_int, digits_frac;
826 int new_len, new_frac_len;
842 digits_int= new_point - beg;
843 set_if_bigger(digits_int, 0);
844 digits_frac= end - new_point;
845 set_if_bigger(digits_frac, 0);
847 if ((new_len= round_up(digits_int) + (new_frac_len= round_up(digits_frac))) >
850 int lack= new_len - dec->len;
853 if (new_frac_len < lack)
854 return E_DEC_OVERFLOW;
857 err= E_DEC_TRUNCATED;
859 diff= digits_frac - (new_frac_len * DIG_PER_DEC1);
863 digits_frac= new_frac_len * DIG_PER_DEC1;
873 return E_DEC_TRUNCATED;
877 if (shift % DIG_PER_DEC1)
879 int l_mini_shift, r_mini_shift, mini_shift;
887 l_mini_shift= shift % DIG_PER_DEC1;
888 r_mini_shift= DIG_PER_DEC1 - l_mini_shift;
894 do_left= l_mini_shift <= beg;
895 assert(do_left || (dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
899 r_mini_shift= (-shift) % DIG_PER_DEC1;
900 l_mini_shift= DIG_PER_DEC1 - r_mini_shift;
902 do_left= !((dec->len * DIG_PER_DEC1 - end) >= r_mini_shift);
903 assert(!do_left || l_mini_shift <= beg);
908 mini_shift= (-l_mini_shift);
913 mini_shift= r_mini_shift;
915 new_point+= mini_shift;
920 if (!(shift+= mini_shift) && (new_point - digits_int) < DIG_PER_DEC1)
922 dec->intg= digits_int;
923 dec->frac= digits_frac;
931 if ((new_front= (new_point - digits_int)) >= DIG_PER_DEC1 ||
940 d_shift= new_front / DIG_PER_DEC1;
941 to= dec->buf + (round_up(beg + 1) - 1 - d_shift);
942 barier= dec->buf + (round_up(end) - 1 - d_shift);
943 assert(to >= dec->buf);
944 assert(barier + d_shift < dec->buf + dec->len);
945 for(; to <= barier; to++)
946 *to= *(to + d_shift);
947 for(barier+= d_shift; to <= barier; to++)
954 d_shift= (1 - new_front) / DIG_PER_DEC1;
955 to= dec->buf + round_up(end) - 1 + d_shift;
956 barier= dec->buf + round_up(beg + 1) - 1 + d_shift;
957 assert(to < dec->buf + dec->len);
958 assert(barier - d_shift >= dec->buf);
959 for(; to >= barier; to--)
960 *to= *(to - d_shift);
961 for(barier-= d_shift; to >= barier; to--)
964 d_shift*= DIG_PER_DEC1;
975 beg= round_up(beg + 1) - 1;
976 end= round_up(end) - 1;
977 assert(new_point >= 0);
981 new_point= round_up(new_point) - 1;
987 dec->buf[new_point]=0;
988 }
while (--new_point > end);
992 for (; new_point < beg; new_point++)
993 dec->buf[new_point]= 0;
995 dec->intg= digits_int;
996 dec->frac= digits_frac;
1024 char *end_of_string = *end;
1026 int i, intg, frac, error, intg1, frac1;
1030 error= E_DEC_BAD_NUM;
1031 while (s < end_of_string && my_charset_utf8_general_ci.isspace(*s))
1033 if (s == end_of_string)
1036 if ((to->sign= (*s ==
'-')))
1042 while (s < end_of_string && my_charset_utf8_general_ci.isdigit(*s))
1045 if (s < end_of_string && *s==
'.')
1048 while (endp < end_of_string && my_charset_utf8_general_ci.isdigit(*endp))
1050 frac= (int) (endp - s - 1);
1066 if (frac > to->frac)
1068 error=E_DEC_TRUNCATED;
1071 if (intg > to->intg)
1073 error=E_DEC_OVERFLOW;
1076 intg1=round_up(intg);
1077 frac1=round_up(frac);
1078 if (intg1+frac1 > to->len)
1086 intg1=round_up(intg);
1087 frac1=round_up(frac);
1088 fix_intg_frac_error(to->len, intg1, frac1, error);
1089 if (unlikely(error))
1091 frac=frac1*DIG_PER_DEC1;
1092 if (error == E_DEC_OVERFLOW)
1093 intg=intg1*DIG_PER_DEC1;
1103 for (x=0, i=0; intg; intg--)
1105 x+= (*--s -
'0')*powers10[i];
1107 if (unlikely(++i == DIG_PER_DEC1))
1118 for (x=0, i=0; frac; frac--)
1120 x= (*++s1 -
'0') + x*10;
1122 if (unlikely(++i == DIG_PER_DEC1))
1130 *buf=x*powers10[DIG_PER_DEC1-i];
1133 if (endp+1 < end_of_string && (*endp ==
'e' || *endp ==
'E'))
1136 const int64_t exponent= internal::my_strtoll10(endp+1, (
char**) &end_of_string,
1139 if (end_of_string != endp +1)
1141 *end= (
char*) end_of_string;
1144 error= E_DEC_BAD_NUM;
1147 if (exponent > INT_MAX/2 || (str_error == 0 && exponent < 0))
1149 error= E_DEC_OVERFLOW;
1152 if (exponent < INT_MIN/2 && error != E_DEC_OVERFLOW)
1154 error= E_DEC_TRUNCATED;
1157 if (error != E_DEC_OVERFLOW)
1181 char strbuf[FLOATING_POINT_BUFFER];
1182 int len=
sizeof(strbuf);
1184 char* end= strbuf + len;
1186 *to= internal::my_strtod(strbuf, &end, &error);
1187 return rc != E_DEC_OK ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
1202 char buff[FLOATING_POINT_BUFFER], *end;
1204 end= buff + internal::my_gcvt(from,
1205 internal::MY_GCVT_ARG_DOUBLE,
1206 sizeof(buff) - 1, buff, NULL);
1207 res= string2decimal(buff, to, &end);
1212 static int ull2dec(uint64_t from, decimal_t *to)
1214 int intg1, error=E_DEC_OK;
1220 for (intg1=1; from >= DIG_BASE; intg1++, from/=DIG_BASE) {};
1221 if (unlikely(intg1 > to->len))
1224 error=E_DEC_OVERFLOW;
1227 to->intg=intg1*DIG_PER_DEC1;
1229 for (buf=to->buf+intg1; intg1; intg1--)
1231 uint64_t y=x/DIG_BASE;
1232 *--buf=(dec1)(x-y*DIG_BASE);
1238 int uint64_t2decimal(
const uint64_t from, decimal_t *to)
1241 return ull2dec(from, to);
1244 int int64_t2decimal(
const int64_t from, decimal_t *to)
1246 if ((to->sign= from < 0))
1247 return ull2dec(-from, to);
1248 return ull2dec(from, to);
1251 int decimal2uint64_t(
const decimal_t *from, uint64_t *to)
1253 dec1 *buf=from->buf;
1260 return E_DEC_OVERFLOW;
1263 for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1266 x=x*DIG_BASE + *buf++;
1267 if (unlikely(y > ((uint64_t) UINT64_MAX/DIG_BASE) || x < y))
1270 return E_DEC_OVERFLOW;
1274 for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1276 return E_DEC_TRUNCATED;
1280 int decimal2int64_t(
const decimal_t *from, int64_t *to)
1282 dec1 *buf=from->buf;
1286 for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1295 x=x*DIG_BASE - *buf++;
1296 if (unlikely(y < (INT64_MIN/DIG_BASE) || x > y))
1302 *to= from->sign ? INT64_MIN : INT64_MAX;
1303 return E_DEC_OVERFLOW;
1307 if (unlikely(from->sign==0 && x == INT64_MIN))
1310 return E_DEC_OVERFLOW;
1313 *to=from->sign ? x : -x;
1314 for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
1316 return E_DEC_TRUNCATED;
1401 dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
1402 int error=E_DEC_OK, intg=precision-frac,
1403 isize1, intg1, intg1x, from_intg,
1404 intg0=intg/DIG_PER_DEC1,
1405 frac0=frac/DIG_PER_DEC1,
1406 intg0x=intg-intg0*DIG_PER_DEC1,
1407 frac0x=frac-frac0*DIG_PER_DEC1,
1408 frac1=from->frac/DIG_PER_DEC1,
1409 frac1x=from->frac-frac1*DIG_PER_DEC1,
1410 isize0=intg0*
sizeof(dec1)+dig2bytes[intg0x],
1411 fsize0=frac0*
sizeof(dec1)+dig2bytes[frac0x],
1412 fsize1=frac1*
sizeof(dec1)+dig2bytes[frac1x];
1413 const int orig_isize0= isize0;
1414 const int orig_fsize0= fsize0;
1415 unsigned char *orig_to= to;
1417 buf1= remove_leading_zeroes(from, &from_intg);
1419 if (unlikely(from_intg+fsize1==0))
1426 intg1=from_intg/DIG_PER_DEC1;
1427 intg1x=from_intg-intg1*DIG_PER_DEC1;
1428 isize1=intg1*
sizeof(dec1)+dig2bytes[intg1x];
1430 if (intg < from_intg)
1432 buf1+=intg1-intg0+(intg1x>0)-(intg0x>0);
1433 intg1=intg0; intg1x=intg0x;
1434 error=E_DEC_OVERFLOW;
1436 else if (isize0 > isize1)
1438 while (isize0-- > isize1)
1441 if (fsize0 < fsize1)
1443 frac1=frac0; frac1x=frac0x;
1444 error=E_DEC_TRUNCATED;
1446 else if (fsize0 > fsize1 && frac1x)
1463 int i=dig2bytes[intg1x];
1464 dec1 x=(*buf1++ % powers10[intg1x]) ^ mask;
1467 case 1: mi_int1store(to, x);
break;
1468 case 2: mi_int2store(to, x);
break;
1469 case 3: mi_int3store(to, x);
break;
1470 case 4: mi_int4store(to, x);
break;
1477 for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=
sizeof(dec1))
1479 dec1 x=*buf1++ ^ mask;
1480 assert(
sizeof(dec1) == 4);
1481 mi_int4store(to, x);
1488 int i=dig2bytes[frac1x],
1489 lim=(frac1 < frac0 ? DIG_PER_DEC1 : frac0x);
1490 while (frac1x < lim && dig2bytes[frac1x] == i)
1492 x=(*buf1 / powers10[DIG_PER_DEC1 - frac1x]) ^ mask;
1495 case 1: mi_int1store(to, x);
break;
1496 case 2: mi_int2store(to, x);
break;
1497 case 3: mi_int3store(to, x);
break;
1498 case 4: mi_int4store(to, x);
break;
1503 if (fsize0 > fsize1)
1505 unsigned char *to_end= orig_to + orig_fsize0 + orig_isize0;
1507 while (fsize0-- > fsize1 && to < to_end)
1508 *to++= (
unsigned char)mask;
1513 assert(to == orig_to + orig_fsize0 + orig_isize0);
1534 int error=E_DEC_OK, intg=precision-scale,
1535 intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1536 intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
1537 intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
1538 dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
1539 const unsigned char *stop;
1540 unsigned char *d_copy;
1544 d_copy= (
unsigned char*) alloca(bin_size);
1545 memcpy(d_copy, from, bin_size);
1549 fix_intg_frac_error(to->len, intg1, frac1, error);
1550 if (unlikely(error))
1552 if (intg1 < intg0+(intg0x>0))
1554 from+=dig2bytes[intg0x]+
sizeof(dec1)*(intg0-intg1);
1555 frac0=frac0x=intg0x=0;
1565 to->sign=(mask != 0);
1566 to->intg=intg0*DIG_PER_DEC1+intg0x;
1567 to->frac=frac0*DIG_PER_DEC1+frac0x;
1571 int i=dig2bytes[intg0x];
1575 case 1: x=mi_sint1korr(from);
break;
1576 case 2: x=mi_sint2korr(from);
break;
1577 case 3: x=mi_sint3korr(from);
break;
1578 case 4: x=mi_sint4korr(from);
break;
1583 if (((uint64_t)*buf) >= (uint64_t) powers10[intg0x+1])
1585 if (buf > to->buf || *buf != 0)
1590 for (stop=from+intg0*
sizeof(dec1); from < stop; from+=
sizeof(dec1))
1592 assert(
sizeof(dec1) == 4);
1593 *buf=mi_sint4korr(from) ^ mask;
1594 if (((uint32_t)*buf) > DIG_MAX)
1596 if (buf > to->buf || *buf != 0)
1599 to->intg-=DIG_PER_DEC1;
1601 assert(to->intg >=0);
1602 for (stop=from+frac0*
sizeof(dec1); from < stop; from+=
sizeof(dec1))
1604 assert(
sizeof(dec1) == 4);
1605 *buf=mi_sint4korr(from) ^ mask;
1606 if (((uint32_t)*buf) > DIG_MAX)
1612 int i=dig2bytes[frac0x];
1616 case 1: x=mi_sint1korr(from);
break;
1617 case 2: x=mi_sint2korr(from);
break;
1618 case 3: x=mi_sint3korr(from);
break;
1619 case 4: x=mi_sint4korr(from);
break;
1622 *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
1623 if (((uint32_t)*buf) > DIG_MAX)
1631 return(E_DEC_BAD_NUM);
1641 int intg=precision-scale,
1642 intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
1643 intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1;
1645 assert(scale >= 0 && precision > 0 && scale <= precision);
1646 return intg0*
sizeof(dec1)+dig2bytes[intg0x]+
1647 frac0*
sizeof(dec1)+dig2bytes[frac0x];
1667 decimal_round_mode mode)
1669 int frac0=scale>0 ? round_up(scale) : scale/DIG_PER_DEC1,
1670 frac1=round_up(from->frac), round_digit= 0,
1671 intg0=round_up(from->intg), error=E_DEC_OK, len=to->len,
1672 intg1=round_up(from->intg +
1673 (((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX)));
1674 dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
1681 case HALF_EVEN: round_digit=5;
break;
1682 case CEILING: round_digit= from->sign ? 10 : 0;
break;
1683 case FLOOR: round_digit= from->sign ? 0 : 10;
break;
1684 case TRUNCATE: round_digit=10;
break;
1688 if (unlikely(frac0+intg0 > len))
1691 scale=frac0*DIG_PER_DEC1;
1692 error=E_DEC_TRUNCATED;
1695 if (scale+from->intg < 0)
1701 if (to != from || intg1>intg0)
1703 dec1 *p0= buf0+intg0+max(frac1, frac0);
1704 dec1 *p1= buf1+intg1+max(frac1, frac0);
1708 if (unlikely(intg1 > intg0))
1714 to->sign=from->sign;
1715 to->intg=min(intg0, len)*DIG_PER_DEC1;
1721 while (frac0-- > frac1)
1726 if (scale >= from->frac)
1729 buf0+=intg0+frac0-1;
1730 buf1+=intg0+frac0-1;
1731 if (scale == frac0*DIG_PER_DEC1)
1734 assert(frac0+intg0 >= 0);
1735 switch (round_digit) {
1738 dec1 *p0= buf0 + (frac1-frac0);
1739 for (; p0 > buf0; p0--)
1751 x= buf0[1]/DIG_MASK;
1752 do_inc= (x>5) || ((x == 5) &&
1753 (mode == HALF_UP || (frac0+intg0 > 0 && *buf0 & 1)));
1766 else if (frac0+intg0==0)
1775 int pos=frac0*DIG_PER_DEC1-scale-1;
1776 assert(frac0+intg0 > 0);
1777 x=*buf1 / powers10[pos];
1779 if (y > round_digit ||
1780 (round_digit == 5 && y == 5 && (mode == HALF_UP || (x/10) & 1)))
1782 *buf1=powers10[pos]*(x-y);
1796 dec1 *buf= to->buf + ((scale == 0 && intg0 == 0) ? 1 : intg0 + frac0);
1797 dec1 *end= to->buf + len;
1802 if (*buf1 >= DIG_BASE)
1806 while (carry && --buf1 >= to->buf)
1807 add(*buf1, *buf1, 0, carry);
1808 if (unlikely(carry))
1811 if (frac0+intg0 >= len)
1814 scale=frac0*DIG_PER_DEC1;
1815 error=E_DEC_TRUNCATED;
1817 for (buf1=to->buf+intg0+max(frac0,0); buf1 > to->buf; buf1--)
1831 if (buf1-- == to->buf)
1834 dec1 *p0= to->buf + frac0 + 1;
1836 to->frac= max(scale, 0);
1838 for (buf1= to->buf; buf1<p0; buf1++)
1846 first_dig= to->intg % DIG_PER_DEC1;
1847 if (first_dig && (*buf1 >= powers10[first_dig]))
1858 static int do_add(
const decimal_t *from1,
const decimal_t *from2, decimal_t *to)
1860 int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
1861 frac1=round_up(from1->frac), frac2=round_up(from2->frac),
1862 frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
1863 dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
1868 x=intg1 > intg2 ? from1->buf[0] :
1869 intg2 > intg1 ? from2->buf[0] :
1870 from1->buf[0] + from2->buf[0] ;
1871 if (unlikely(x > DIG_MAX-1))
1877 fix_intg_frac_error(to->len, intg0, frac0, error);
1878 if (unlikely(error == E_DEC_OVERFLOW))
1884 buf0=to->buf+intg0+frac0;
1886 to->sign=from1->sign;
1887 to->frac=max(from1->frac, from2->frac);
1888 to->intg=intg0*DIG_PER_DEC1;
1889 if (unlikely(error))
1891 set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
1892 set_if_smaller(frac1, frac0);
1893 set_if_smaller(frac2, frac0);
1894 set_if_smaller(intg1, intg0);
1895 set_if_smaller(intg2, intg0);
1901 buf1=from1->buf+intg1+frac1;
1902 stop=from1->buf+intg1+frac2;
1903 buf2=from2->buf+intg2+frac2;
1904 stop2=from1->buf+(intg1 > intg2 ? intg1-intg2 : 0);
1908 buf1=from2->buf+intg2+frac2;
1909 stop=from2->buf+intg2+frac1;
1910 buf2=from1->buf+intg1+frac1;
1911 stop2=from2->buf+(intg2 > intg1 ? intg2-intg1 : 0);
1918 while (buf1 > stop2)
1920 add(*--buf0, *--buf1, *--buf2, carry);
1924 buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
1925 ((stop=from2->buf)+intg2-intg1) ;
1928 add(*--buf0, *--buf1, 0, carry);
1931 if (unlikely(carry))
1933 assert(buf0 == to->buf || buf0 == to->buf+1);
1940 static int do_sub(
const decimal_t *from1,
const decimal_t *from2, decimal_t *to)
1942 int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
1943 frac1=round_up(from1->frac), frac2=round_up(from2->frac);
1944 int frac0=max(frac1, frac2), error;
1945 dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
1948 start1=buf1=from1->buf; stop1=buf1+intg1;
1949 start2=buf2=from2->buf; stop2=buf2+intg2;
1950 if (unlikely(*buf1 == 0))
1952 while (buf1 < stop1 && *buf1 == 0)
1955 intg1= (int) (stop1-buf1);
1957 if (unlikely(*buf2 == 0))
1959 while (buf2 < stop2 && *buf2 == 0)
1962 intg2= (int) (stop2-buf2);
1966 else if (intg2 == intg1)
1968 dec1 *end1= stop1 + (frac1 - 1);
1969 dec1 *end2= stop2 + (frac2 - 1);
1970 while (unlikely((buf1 <= end1) && (*end1 == 0)))
1972 while (unlikely((buf2 <= end2) && (*end2 == 0)))
1974 frac1= (int) (end1 - stop1) + 1;
1975 frac2= (int) (end2 - stop2) + 1;
1976 while (buf1 <=end1 && buf2 <= end2 && *buf1 == *buf2)
1981 carry= *buf2 > *buf1;
2002 return carry == from1->sign ? 1 : -1;
2006 to->sign=from1->sign;
2012 swap(start1, start2);
2015 to->sign= 1 - to->sign;
2018 fix_intg_frac_error(to->len, intg1, frac0, error);
2019 buf0=to->buf+intg1+frac0;
2021 to->frac=max(from1->frac, from2->frac);
2022 to->intg=intg1*DIG_PER_DEC1;
2023 if (unlikely(error))
2025 set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
2026 set_if_smaller(frac1, frac0);
2027 set_if_smaller(frac2, frac0);
2028 set_if_smaller(intg2, intg1);
2035 buf1=start1+intg1+frac1;
2036 stop1=start1+intg1+frac2;
2037 buf2=start2+intg2+frac2;
2038 while (frac0-- > frac1)
2040 while (buf1 > stop1)
2045 buf1=start1+intg1+frac1;
2046 buf2=start2+intg2+frac2;
2047 stop2=start2+intg2+frac1;
2048 while (frac0-- > frac2)
2050 while (buf2 > stop2)
2052 sub(*--buf0, 0, *--buf2, carry);
2057 while (buf2 > start2)
2059 sub(*--buf0, *--buf1, *--buf2, carry);
2063 while (carry && buf1 > start1)
2065 sub(*--buf0, *--buf1, 0, carry);
2068 while (buf1 > start1)
2071 while (buf0 > to->buf)
2077 int decimal_intg(
const decimal_t *from)
2080 remove_leading_zeroes(from, &res);
2084 int decimal_add(
const decimal_t *from1,
const decimal_t *from2, decimal_t *to)
2086 if (likely(from1->sign == from2->sign))
2087 return do_add(from1, from2, to);
2088 return do_sub(from1, from2, to);
2091 int decimal_sub(
const decimal_t *from1,
const decimal_t *from2, decimal_t *to)
2093 if (likely(from1->sign == from2->sign))
2094 return do_sub(from1, from2, to);
2095 return do_add(from1, from2, to);
2098 int decimal_cmp(
const decimal_t *from1,
const decimal_t *from2)
2100 if (likely(from1->sign == from2->sign))
2101 return do_sub(from1, from2, 0);
2102 return from1->sign > from2->sign ? -1 : 1;
2105 int decimal_t::isZero()
const
2108 *end= buf1 +round_up(intg) +round_up(frac);
2143 int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
2144 frac1=round_up(from1->frac), frac2=round_up(from2->frac),
2145 intg0=round_up(from1->intg+from2->intg),
2146 frac0=frac1+frac2, error, i, j, d_to_move;
2147 dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
2148 *start2, *stop2, *stop1, *start0, carry;
2154 fix_intg_frac_error(to->len, intg0, frac0, error);
2155 to->sign=from1->sign != from2->sign;
2156 to->frac=from1->frac+from2->frac;
2157 to->intg=intg0*DIG_PER_DEC1;
2159 if (unlikely(error))
2161 set_if_smaller(to->frac, frac0*DIG_PER_DEC1);
2162 set_if_smaller(to->intg, intg0*DIG_PER_DEC1);
2163 if (unlikely(i > intg0))
2179 start0=to->buf+intg0+frac0-1;
2180 start2=buf2+frac2-1;
2184 memset(to->buf, 0, (intg0+frac0)*
sizeof(dec1));
2186 for (buf1+=frac1-1; buf1 >= stop1; buf1--, start0--)
2189 for (buf0=start0, buf2=start2; buf2 >= stop2; buf2--, buf0--)
2192 dec2 p= ((dec2)*buf1) * ((dec2)*buf2);
2193 hi=(dec1)(p/DIG_BASE);
2194 lo=(dec1)(p-((dec2)hi)*DIG_BASE);
2195 add2(*buf0, *buf0, lo, carry);
2201 return E_DEC_OVERFLOW;
2202 add2(*buf0, *buf0, 0, carry);
2204 for (buf0--; carry; buf0--)
2207 return E_DEC_OVERFLOW;
2208 add(*buf0, *buf0, 0, carry);
2216 dec1 *end= to->buf + intg0 + frac0;
2231 d_to_move= intg0 + round_up(to->frac);
2232 while (!*buf1 && (to->intg > DIG_PER_DEC1))
2235 to->intg-= DIG_PER_DEC1;
2240 dec1 *cur_d= to->buf;
2241 for (; d_to_move--; cur_d++, buf1++)
2261 int frac1=round_up(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2262 frac2=round_up(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2263 error= 0, i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2264 dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2265 *start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
2266 dec2 norm_factor, x, guess, y;
2274 i= ((prec2 - 1) % DIG_PER_DEC1) + 1;
2275 while (prec2 > 0 && *buf2 == 0)
2282 return E_DEC_DIV_ZERO;
2283 for (i= (prec2 - 1) % DIG_PER_DEC1; *buf2 < powers10[i--]; prec2--) ;
2286 i=((prec1-1) % DIG_PER_DEC1)+1;
2287 while (prec1 > 0 && *buf1 == 0)
2298 for (i=(prec1-1) % DIG_PER_DEC1; *buf1 < powers10[i--]; prec1--) ;
2302 if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0)
2305 dintg=(prec1-frac1)-(prec2-frac2)+(*buf1 >= *buf2);
2308 dintg/=DIG_PER_DEC1;
2312 intg0=round_up(dintg);
2320 to->sign=from1->sign;
2321 to->frac=max(from1->frac, from2->frac);
2336 frac0=round_up(frac1+frac2+scale_incr);
2337 fix_intg_frac_error(to->len, intg0, frac0, error);
2338 to->sign=from1->sign != from2->sign;
2339 to->intg=intg0*DIG_PER_DEC1;
2340 to->frac=frac0*DIG_PER_DEC1;
2343 stop0=buf0+intg0+frac0;
2344 if (likely(div_mod))
2348 len1=(i=round_up(prec1))+round_up(2*frac2+scale_incr+1) + 1;
2349 set_if_bigger(len1, 3);
2350 if (!(tmp1=(dec1 *)alloca(len1*
sizeof(dec1))))
2352 memcpy(tmp1, buf1, i*
sizeof(dec1));
2353 memset(tmp1+i, 0, (len1-i)*
sizeof(dec1));
2358 stop2=buf2+round_up(prec2)-1;
2361 while (*stop2 == 0 && stop2 >= start2)
2363 len2= (int) (stop2++ - start2);
2373 norm_factor=DIG_BASE/(*start2+1);
2374 norm2=(dec1)(norm_factor*start2[0]);
2376 norm2+=(dec1)(norm_factor*start2[1]/DIG_BASE);
2378 if (*start1 < *start2)
2384 for (; buf0 < stop0; buf0++)
2387 if (unlikely(dcarry == 0 && *start1 < *start2))
2392 x=start1[0]+((dec2)dcarry)*DIG_BASE;
2394 guess=(norm_factor*x+norm_factor*y/DIG_BASE)/norm2;
2395 if (unlikely(guess >= DIG_BASE))
2400 if (start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y)
2402 if (unlikely(start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y))
2404 assert(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y);
2410 assert(buf1 < stop1);
2411 for (carry=0; buf2 > start2; buf1--)
2414 x=guess * (*--buf2);
2415 hi=(dec1)(x/DIG_BASE);
2416 lo=(dec1)(x-((dec2)hi)*DIG_BASE);
2417 sub2(*buf1, *buf1, lo, carry);
2420 carry= dcarry < carry;
2423 if (unlikely(carry))
2429 for (carry=0; buf2 > start2; buf1--)
2431 add(*buf1, *buf1, *--buf2, carry);
2435 if (likely(div_mod))
2450 intg0=(int) (round_up(prec1-frac1)-(start1-tmp1));
2451 frac0=round_up(to->frac);
2453 if (unlikely(frac0==0 && intg0==0))
2460 if (unlikely(-intg0 >= to->len))
2463 error=E_DEC_TRUNCATED;
2474 if (unlikely(intg0 > to->len))
2478 error=E_DEC_OVERFLOW;
2481 assert(intg0 <= round_up(from2->intg));
2482 stop1=start1+frac0+intg0;
2483 to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
2485 if (unlikely(intg0+frac0 > to->len))
2487 stop1-=frac0+intg0-to->len;
2488 frac0=to->len-intg0;
2489 to->frac=frac0*DIG_PER_DEC1;
2490 error=E_DEC_TRUNCATED;
2492 assert(buf0 + (stop1 - start1) <= to->buf + to->len);
2493 while (start1 < stop1)
2516 return do_div_mod(from1, from2, to, 0, scale_incr);
2549 std::ostream& operator<<(std::ostream& output,
const type::Decimal &dec)
2555 output <<
"type::Decimal:(";
2556 output << str.c_ptr();
2568 char buf1[100], buf2[100], buf3[100];
2570 void dump_decimal(decimal_t *d)
2573 printf(
"/* intg=%d, frac=%d, sign=%d, buf[]={", d->intg, d->frac, d->sign);
2574 for (i=0; i < round_up(d->frac)+round_up(d->intg)-1; i++)
2575 printf(
"%09d, ", d->buf[i]);
2576 printf(
"%09d} */ ", d->buf[i]);
2580 void check_result_code(
int actual,
int want)
2584 printf(
"\n^^^^^^^^^^^^^ must return %d\n", want);
2590 void print_decimal(decimal_t *d,
const char *orig,
int actual,
int want)
2595 if (full) dump_decimal(d);
2598 check_result_code(actual, want);
2599 if (orig && strcmp(orig, s))
2601 printf(
"\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2612 printf(
"==== decimal2string ====\n");
2613 a.buf[0]=12345; a.intg=5; a.frac=0; a.sign=0;
2616 dump_decimal(&a); printf(
" --> res=%d str='%s' len=%d\n", res, s, slen);
2618 a.buf[1]=987000000; a.frac=3;
2621 dump_decimal(&a); printf(
" --> res=%d str='%s' len=%d\n", res, s, slen);
2626 dump_decimal(&a); printf(
" --> res=%d str='%s' len=%d\n", res, s, slen);
2630 dump_decimal(&a); printf(
" --> res=%d str='%s' len=%d\n", res, s, slen);
2634 dump_decimal(&a); printf(
" --> res=%d str='%s' len=%d\n", res, s, slen);
2636 a.buf[0]=987000000; a.frac=3; a.intg=0;
2639 dump_decimal(&a); printf(
" --> res=%d str='%s' len=%d\n", res, s, slen);
2642 void test_s2d(
const char *s,
const char *orig,
int ex)
2646 snprintf(s1,
sizeof(s1),
"'%s'", s);
2648 printf(
"len=%2d %-30s => res=%d ", a.len, s1,
2649 (res= string2decimal(s, &a, &end)));
2650 print_decimal(&a, orig, res, ex);
2654 void test_d2f(
const char *s,
int ex)
2660 snprintf(s1,
sizeof(s1),
"'%s'", s);
2662 string2decimal(s, &a, &end);
2664 if (full) dump_decimal(&a);
2665 printf(
"%-40s => res=%d %.*g\n", s1, res, a.intg+a.frac, x);
2666 check_result_code(res, ex);
2669 void test_d2b2d(
const char *str,
int p,
int s,
const char *orig,
int ex)
2671 char s1[100], buf[100], *end;
2674 snprintf(s1,
sizeof(s1),
"'%s'", str);
2676 string2decimal(str, &a, &end);
2678 printf(
"%-31s {%2d, %2d} => res=%d size=%-2d ", s1, p, s, res, size);
2682 for (
int i= 0; i < size; i++)
2683 printf(
"%02x", ((
unsigned char *)buf)[i]);
2686 printf(
" => res=%d ", res);
2687 print_decimal(&a, orig, res, ex);
2691 void test_f2d(
double from,
int ex)
2696 printf(
"%-40.*f => res=%d ", DBL_DIG-2, from, res);
2697 print_decimal(&a, 0, res, ex);
2701 void test_ull2d(uint64_t from,
const char *orig,
int ex)
2706 res=uint64_t2decimal(from, &a);
2707 internal::int64_t10_to_str(from,s,10);
2708 printf(
"%-40s => res=%d ", s, res);
2709 print_decimal(&a, orig, res, ex);
2713 void test_ll2d(int64_t from,
const char *orig,
int ex)
2718 res=int64_t2decimal(from, &a);
2719 internal::int64_t10_to_str(from,s,-10);
2720 printf(
"%-40s => res=%d ", s, res);
2721 print_decimal(&a, orig, res, ex);
2725 void test_d2ull(
const char *s,
const char *orig,
int ex)
2732 string2decimal(s, &a, &end);
2733 res=decimal2uint64_t(&a, &x);
2734 if (full) dump_decimal(&a);
2735 internal::int64_t10_to_str(x,s1,10);
2736 printf(
"%-40s => res=%d %s\n", s, res, s1);
2737 check_result_code(res, ex);
2738 if (orig && strcmp(orig, s1))
2740 printf(
"\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2745 void test_d2ll(
const char *s,
const char *orig,
int ex)
2752 string2decimal(s, &a, &end);
2753 res=decimal2int64_t(&a, &x);
2754 if (full) dump_decimal(&a);
2755 internal::int64_t10_to_str(x,s1,-10);
2756 printf(
"%-40s => res=%d %s\n", s, res, s1);
2757 check_result_code(res, ex);
2758 if (orig && strcmp(orig, s1))
2760 printf(
"\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2765 void test_da(
const char *s1,
const char *s2,
const char *orig,
int ex)
2769 snprintf(s,
sizeof(s),
"'%s' + '%s'", s1, s2);
2771 string2decimal(s1, &a, &end);
2773 string2decimal(s2, &b, &end);
2774 res=decimal_add(&a, &b, &c);
2775 printf(
"%-40s => res=%d ", s, res);
2776 print_decimal(&c, orig, res, ex);
2780 void test_ds(
const char *s1,
const char *s2,
const char *orig,
int ex)
2784 snprintf(s,
sizeof(s),
"'%s' - '%s'", s1, s2);
2786 string2decimal(s1, &a, &end);
2788 string2decimal(s2, &b, &end);
2789 res=decimal_sub(&a, &b, &c);
2790 printf(
"%-40s => res=%d ", s, res);
2791 print_decimal(&c, orig, res, ex);
2795 void test_dc(
const char *s1,
const char *s2,
int orig)
2799 snprintf(s,
sizeof(s),
"'%s' <=> '%s'", s1, s2);
2801 string2decimal(s1, &a, &end);
2803 string2decimal(s2, &b, &end);
2804 res=decimal_cmp(&a, &b);
2805 printf(
"%-40s => res=%d\n", s, res);
2808 printf(
"\n^^^^^^^^^^^^^ must've been %d\n", orig);
2813 void test_dm(
const char *s1,
const char *s2,
const char *orig,
int ex)
2817 snprintf(s,
sizeof(s),
"'%s' * '%s'", s1, s2);
2819 string2decimal(s1, &a, &end);
2821 string2decimal(s2, &b, &end);
2823 printf(
"%-40s => res=%d ", s, res);
2824 print_decimal(&c, orig, res, ex);
2828 void test_dv(
const char *s1,
const char *s2,
const char *orig,
int ex)
2832 snprintf(s,
sizeof(s),
"'%s' / '%s'", s1, s2);
2834 string2decimal(s1, &a, &end);
2836 string2decimal(s2, &b, &end);
2838 printf(
"%-40s => res=%d ", s, res);
2839 check_result_code(res, ex);
2840 if (res == E_DEC_DIV_ZERO)
2841 printf(
"E_DEC_DIV_ZERO");
2843 print_decimal(&c, orig, res, ex);
2847 void test_md(
const char *s1,
const char *s2,
const char *orig,
int ex)
2851 snprintf(s,
sizeof(s),
"'%s' %% '%s'", s1, s2);
2853 string2decimal(s1, &a, &end);
2855 string2decimal(s2, &b, &end);
2857 printf(
"%-40s => res=%d ", s, res);
2858 check_result_code(res, ex);
2859 if (res == E_DEC_DIV_ZERO)
2860 printf(
"E_DEC_DIV_ZERO");
2862 print_decimal(&c, orig, res, ex);
2866 const char *round_mode[]=
2867 {
"TRUNCATE",
"HALF_EVEN",
"HALF_UP",
"CEILING",
"FLOOR"};
2869 void test_ro(
const char *s1,
int n, decimal_round_mode mode,
const char *orig,
2874 snprintf(s,
sizeof(s),
"'%s', %d, %s", s1, n, round_mode[mode]);
2876 string2decimal(s1, &a, &end);
2878 printf(
"%-40s => res=%d ", s, res);
2879 print_decimal(&b, orig, res, ex);
2884 void test_mx(
int precision,
int frac,
const char *orig)
2887 snprintf(s,
sizeof(s),
"%d, %d", precision, frac);
2889 printf(
"%-40s => ", s);
2890 print_decimal(&a, orig, 0, 0);
2895 void test_pr(
const char *s1,
int prec,
int dec,
char filler,
const char *orig,
2900 int slen=
sizeof(s2);
2903 snprintf(s,
sizeof(s), filler ?
"'%s', %d, %d, '%c'" :
"'%s', %d, %d, '\\0'",
2904 s1, prec, dec, filler);
2906 string2decimal(s1, &a, &end);
2908 printf(
"%-40s => res=%d '%s'", s, res, s2);
2909 check_result_code(res, ex);
2910 if (orig && strcmp(orig, s2))
2912 printf(
"\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
2919 void test_sh(
const char *s1,
int shift,
const char *orig,
int ex)
2923 snprintf(s,
sizeof(s),
"'%s' %s %d", s1, ((shift < 0) ?
">>" :
"<<"), abs(shift));
2925 string2decimal(s1, &a, &end);
2927 printf(
"%-40s => res=%d ", s, res);
2928 print_decimal(&a, orig, res, ex);
2933 void test_fr(
const char *s1,
const char *orig)
2936 snprintf(s,
sizeof(s),
"'%s'", s1);
2937 printf(
"%-40s => ", s);
2939 string2decimal(s1, &a, &end);
2941 print_decimal(&a, orig, 0, 0);
2949 a.len=
sizeof(buf1)/
sizeof(dec1);
2951 b.len=
sizeof(buf2)/
sizeof(dec1);
2953 c.len=
sizeof(buf3)/
sizeof(dec1);
2958 printf(
"==== string2decimal ====\n");
2959 test_s2d(
"12345",
"12345", 0);
2960 test_s2d(
"12345.",
"12345", 0);
2961 test_s2d(
"123.45",
"123.45", 0);
2962 test_s2d(
"-123.45",
"-123.45", 0);
2963 test_s2d(
".00012345000098765",
"0.00012345000098765", 0);
2964 test_s2d(
".12345000098765",
"0.12345000098765", 0);
2965 test_s2d(
"-.000000012345000098765",
"-0.000000012345000098765", 0);
2966 test_s2d(
"1234500009876.5",
"1234500009876.5", 0);
2968 test_s2d(
"123450000098765",
"98765", 2);
2969 test_s2d(
"123450.000098765",
"123450", 1);
2970 a.len=
sizeof(buf1)/
sizeof(dec1);
2971 test_s2d(
"123E5",
"12300000", 0);
2972 test_s2d(
"123E-2",
"1.23", 0);
2974 printf(
"==== decimal2double ====\n");
2975 test_d2f(
"12345", 0);
2976 test_d2f(
"123.45", 0);
2977 test_d2f(
"-123.45", 0);
2978 test_d2f(
"0.00012345000098765", 0);
2979 test_d2f(
"1234500009876.5", 0);
2981 printf(
"==== double2decimal ====\n");
2984 test_f2d(-123.45, 0);
2985 test_f2d(0.00012345000098765, 0);
2986 test_f2d(1234500009876.5, 0);
2988 printf(
"==== uint64_t2decimal ====\n");
2989 test_ull2d(12345ULL,
"12345", 0);
2990 test_ull2d(0ULL,
"0", 0);
2991 test_ull2d(18446744073709551615ULL,
"18446744073709551615", 0);
2993 printf(
"==== decimal2uint64_t ====\n");
2994 test_d2ull(
"12345",
"12345", 0);
2995 test_d2ull(
"0",
"0", 0);
2996 test_d2ull(
"18446744073709551615",
"18446744073709551615", 0);
2997 test_d2ull(
"18446744073709551616",
"18446744073", 2);
2998 test_d2ull(
"-1",
"0", 2);
2999 test_d2ull(
"1.23",
"1", 1);
3000 test_d2ull(
"9999999999999999999999999.000",
"9999999999999999", 2);
3002 printf(
"==== int64_t2decimal ====\n");
3003 test_ll2d(12345LL,
"-12345", 0);
3004 test_ll2d(1LL,
"-1", 0);
3005 test_ll2d(9223372036854775807LL,
"-9223372036854775807", 0);
3006 test_ll2d(9223372036854775808ULL,
"-9223372036854775808", 0);
3008 printf(
"==== decimal2int64_t ====\n");
3009 test_d2ll(
"18446744073709551615",
"18446744073", 2);
3010 test_d2ll(
"-1",
"-1", 0);
3011 test_d2ll(
"-1.23",
"-1", 1);
3012 test_d2ll(
"-9223372036854775807",
"-9223372036854775807", 0);
3013 test_d2ll(
"-9223372036854775808",
"-9223372036854775808", 0);
3014 test_d2ll(
"9223372036854775808",
"9223372036854775807", 2);
3016 printf(
"==== do_add ====\n");
3017 test_da(
".00012345000098765" ,
"123.45",
"123.45012345000098765", 0);
3018 test_da(
".1" ,
".45",
"0.55", 0);
3019 test_da(
"1234500009876.5" ,
".00012345000098765",
"1234500009876.50012345000098765", 0);
3020 test_da(
"9999909999999.5" ,
".555",
"9999910000000.055", 0);
3021 test_da(
"99999999" ,
"1",
"100000000", 0);
3022 test_da(
"989999999" ,
"1",
"990000000", 0);
3023 test_da(
"999999999" ,
"1",
"1000000000", 0);
3024 test_da(
"12345" ,
"123.45",
"12468.45", 0);
3025 test_da(
"-12345" ,
"-123.45",
"-12468.45", 0);
3026 test_ds(
"-12345" ,
"123.45",
"-12468.45", 0);
3027 test_ds(
"12345" ,
"-123.45",
"12468.45", 0);
3029 printf(
"==== do_sub ====\n");
3030 test_ds(
".00012345000098765",
"123.45",
"-123.44987654999901235", 0);
3031 test_ds(
"1234500009876.5",
".00012345000098765",
"1234500009876.49987654999901235", 0);
3032 test_ds(
"9999900000000.5",
".555",
"9999899999999.945", 0);
3033 test_ds(
"1111.5551",
"1111.555",
"0.0001", 0);
3034 test_ds(
".555",
".555",
"0", 0);
3035 test_ds(
"10000000",
"1",
"9999999", 0);
3036 test_ds(
"1000001000",
".1",
"1000000999.9", 0);
3037 test_ds(
"1000000000",
".1",
"999999999.9", 0);
3038 test_ds(
"12345",
"123.45",
"12221.55", 0);
3039 test_ds(
"-12345",
"-123.45",
"-12221.55", 0);
3040 test_da(
"-12345",
"123.45",
"-12221.55", 0);
3041 test_da(
"12345",
"-123.45",
"12221.55", 0);
3042 test_ds(
"123.45",
"12345",
"-12221.55", 0);
3043 test_ds(
"-123.45",
"-12345",
"12221.55", 0);
3044 test_da(
"123.45",
"-12345",
"-12221.55", 0);
3045 test_da(
"-123.45",
"12345",
"12221.55", 0);
3046 test_da(
"5",
"-6.0",
"-1.0", 0);
3048 printf(
"==== decimal_mul ====\n");
3049 test_dm(
"12",
"10",
"120", 0);
3050 test_dm(
"-123.456",
"98765.4321",
"-12193185.1853376", 0);
3051 test_dm(
"-123456000000",
"98765432100000",
"-12193185185337600000000000", 0);
3052 test_dm(
"123456",
"987654321",
"121931851853376", 0);
3053 test_dm(
"123456",
"9876543210",
"1219318518533760", 0);
3054 test_dm(
"123",
"0.01",
"1.23", 0);
3055 test_dm(
"123",
"0",
"0", 0);
3057 printf(
"==== decimal_div ====\n");
3058 test_dv(
"120",
"10",
"12.000000000", 0);
3059 test_dv(
"123",
"0.01",
"12300.000000000", 0);
3060 test_dv(
"120",
"100000000000.00000",
"0.000000001200000000", 0);
3061 test_dv(
"123",
"0",
"", 4);
3062 test_dv(
"0",
"0",
"", 4);
3063 test_dv(
"-12193185.1853376",
"98765.4321",
"-123.456000000000000000", 0);
3064 test_dv(
"121931851853376",
"987654321",
"123456.000000000", 0);
3065 test_dv(
"0",
"987",
"0", 0);
3066 test_dv(
"1",
"3",
"0.333333333", 0);
3067 test_dv(
"1.000000000000",
"3",
"0.333333333333333333", 0);
3068 test_dv(
"1",
"1",
"1.000000000", 0);
3069 test_dv(
"0.0123456789012345678912345",
"9999999999",
"0.000000000001234567890246913578148141", 0);
3070 test_dv(
"10.333000000",
"12.34500",
"0.837019036046982584042122316", 0);
3071 test_dv(
"10.000000000060",
"2",
"5.000000000030000000", 0);
3073 printf(
"==== decimal_mod ====\n");
3074 test_md(
"234",
"10",
"4", 0);
3075 test_md(
"234.567",
"10.555",
"2.357", 0);
3076 test_md(
"-234.567",
"10.555",
"-2.357", 0);
3077 test_md(
"234.567",
"-10.555",
"2.357", 0);
3079 test_md(
"99999999999999999999999999999999999999",
"3",
"0", 0);
3080 if (c.buf[1] != 0x3ABECA)
3082 printf(
"%X - overflow\n", c.buf[1]);
3086 printf(
"==== decimal2bin/bin2decimal ====\n");
3087 test_d2b2d(
"-10.55", 4, 2,
"-10.55", 0);
3088 test_d2b2d(
"0.0123456789012345678912345", 30, 25,
"0.0123456789012345678912345", 0);
3089 test_d2b2d(
"12345", 5, 0,
"12345", 0);
3090 test_d2b2d(
"12345", 10, 3,
"12345.000", 0);
3091 test_d2b2d(
"123.45", 10, 3,
"123.450", 0);
3092 test_d2b2d(
"-123.45", 20, 10,
"-123.4500000000", 0);
3093 test_d2b2d(
".00012345000098765", 15, 14,
"0.00012345000098", 0);
3094 test_d2b2d(
".00012345000098765", 22, 20,
"0.00012345000098765000", 0);
3095 test_d2b2d(
".12345000098765", 30, 20,
"0.12345000098765000000", 0);
3096 test_d2b2d(
"-.000000012345000098765", 30, 20,
"-0.00000001234500009876", 0);
3097 test_d2b2d(
"1234500009876.5", 30, 5,
"1234500009876.50000", 0);
3098 test_d2b2d(
"111111111.11", 10, 2,
"11111111.11", 0);
3099 test_d2b2d(
"000000000.01", 7, 3,
"0.010", 0);
3100 test_d2b2d(
"123.4", 10, 2,
"123.40", 0);
3103 printf(
"==== decimal_cmp ====\n");
3104 test_dc(
"12",
"13",-1);
3105 test_dc(
"13",
"12",1);
3106 test_dc(
"-10",
"10",-1);
3107 test_dc(
"10",
"-10",1);
3108 test_dc(
"-12",
"-13",1);
3109 test_dc(
"0",
"12",-1);
3110 test_dc(
"-10",
"0",-1);
3113 printf(
"==== decimal_round ====\n");
3114 test_ro(
"5678.123451",-4,TRUNCATE,
"0", 0);
3115 test_ro(
"5678.123451",-3,TRUNCATE,
"5000", 0);
3116 test_ro(
"5678.123451",-2,TRUNCATE,
"5600", 0);
3117 test_ro(
"5678.123451",-1,TRUNCATE,
"5670", 0);
3118 test_ro(
"5678.123451",0,TRUNCATE,
"5678", 0);
3119 test_ro(
"5678.123451",1,TRUNCATE,
"5678.1", 0);
3120 test_ro(
"5678.123451",2,TRUNCATE,
"5678.12", 0);
3121 test_ro(
"5678.123451",3,TRUNCATE,
"5678.123", 0);
3122 test_ro(
"5678.123451",4,TRUNCATE,
"5678.1234", 0);
3123 test_ro(
"5678.123451",5,TRUNCATE,
"5678.12345", 0);
3124 test_ro(
"5678.123451",6,TRUNCATE,
"5678.123451", 0);
3125 test_ro(
"-5678.123451",-4,TRUNCATE,
"0", 0);
3126 memset(buf2, 33,
sizeof(buf2));
3127 test_ro(
"99999999999999999999999999999999999999",-31,TRUNCATE,
"99999990000000000000000000000000000000", 0);
3128 test_ro(
"15.1",0,HALF_UP,
"15", 0);
3129 test_ro(
"15.5",0,HALF_UP,
"16", 0);
3130 test_ro(
"15.9",0,HALF_UP,
"16", 0);
3131 test_ro(
"-15.1",0,HALF_UP,
"-15", 0);
3132 test_ro(
"-15.5",0,HALF_UP,
"-16", 0);
3133 test_ro(
"-15.9",0,HALF_UP,
"-16", 0);
3134 test_ro(
"15.1",1,HALF_UP,
"15.1", 0);
3135 test_ro(
"-15.1",1,HALF_UP,
"-15.1", 0);
3136 test_ro(
"15.17",1,HALF_UP,
"15.2", 0);
3137 test_ro(
"15.4",-1,HALF_UP,
"20", 0);
3138 test_ro(
"-15.4",-1,HALF_UP,
"-20", 0);
3139 test_ro(
"5.4",-1,HALF_UP,
"10", 0);
3140 test_ro(
".999", 0, HALF_UP,
"1", 0);
3141 memset(buf2, 33,
sizeof(buf2));
3142 test_ro(
"999999999", -9, HALF_UP,
"1000000000", 0);
3143 test_ro(
"15.1",0,HALF_EVEN,
"15", 0);
3144 test_ro(
"15.5",0,HALF_EVEN,
"16", 0);
3145 test_ro(
"14.5",0,HALF_EVEN,
"14", 0);
3146 test_ro(
"15.9",0,HALF_EVEN,
"16", 0);
3147 test_ro(
"15.1",0,CEILING,
"16", 0);
3148 test_ro(
"-15.1",0,CEILING,
"-15", 0);
3149 test_ro(
"15.1",0,FLOOR,
"15", 0);
3150 test_ro(
"-15.1",0,FLOOR,
"-16", 0);
3151 test_ro(
"999999999999999999999.999", 0, CEILING,
"1000000000000000000000", 0);
3152 test_ro(
"-999999999999999999999.999", 0, FLOOR,
"-1000000000000000000000", 0);
3154 b.buf[0]=DIG_BASE+1;
3156 test_ro(
".3", 0, HALF_UP,
"0", 0);
3158 if (b.buf[0] != DIG_BASE+1)
3160 printf(
"%d - underflow\n", b.buf[0]);
3164 printf(
"==== max_decimal ====\n");
3168 test_mx(4,2,
"99.99");
3169 test_mx(6,3,
"999.999");
3170 test_mx(8,4,
"9999.9999");
3171 test_mx(10,5,
"99999.99999");
3172 test_mx(12,6,
"999999.999999");
3173 test_mx(14,7,
"9999999.9999999");
3174 test_mx(16,8,
"99999999.99999999");
3175 test_mx(18,9,
"999999999.999999999");
3176 test_mx(20,10,
"9999999999.9999999999");
3177 test_mx(20,20,
"0.99999999999999999999");
3178 test_mx(20,0,
"99999999999999999999");
3179 test_mx(40,20,
"99999999999999999999.99999999999999999999");
3181 printf(
"==== decimal2string ====\n");
3182 test_pr(
"123.123", 0, 0, 0,
"123.123", 0);
3183 test_pr(
"123.123", 7, 3,
'0',
"123.123", 0);
3184 test_pr(
"123.123", 9, 3,
'0',
"00123.123", 0);
3185 test_pr(
"123.123", 9, 4,
'0',
"0123.1230", 0);
3186 test_pr(
"123.123", 9, 5,
'0',
"123.12300", 0);
3187 test_pr(
"123.123", 9, 2,
'0',
"000123.12", 1);
3188 test_pr(
"123.123", 9, 6,
'0',
"23.123000", 2);
3190 printf(
"==== decimal_shift ====\n");
3191 test_sh(
"123.123", 1,
"1231.23", 0);
3192 test_sh(
"123457189.123123456789000", 1,
"1234571891.23123456789", 0);
3193 test_sh(
"123457189.123123456789000", 4,
"1234571891231.23456789", 0);
3194 test_sh(
"123457189.123123456789000", 8,
"12345718912312345.6789", 0);
3195 test_sh(
"123457189.123123456789000", 9,
"123457189123123456.789", 0);
3196 test_sh(
"123457189.123123456789000", 10,
"1234571891231234567.89", 0);
3197 test_sh(
"123457189.123123456789000", 17,
"12345718912312345678900000", 0);
3198 test_sh(
"123457189.123123456789000", 18,
"123457189123123456789000000", 0);
3199 test_sh(
"123457189.123123456789000", 19,
"1234571891231234567890000000", 0);
3200 test_sh(
"123457189.123123456789000", 26,
"12345718912312345678900000000000000", 0);
3201 test_sh(
"123457189.123123456789000", 27,
"123457189123123456789000000000000000", 0);
3202 test_sh(
"123457189.123123456789000", 28,
"1234571891231234567890000000000000000", 0);
3203 test_sh(
"000000000000000000000000123457189.123123456789000", 26,
"12345718912312345678900000000000000", 0);
3204 test_sh(
"00000000123457189.123123456789000", 27,
"123457189123123456789000000000000000", 0);
3205 test_sh(
"00000000000000000123457189.123123456789000", 28,
"1234571891231234567890000000000000000", 0);
3206 test_sh(
"123", 1,
"1230", 0);
3207 test_sh(
"123", 10,
"1230000000000", 0);
3208 test_sh(
".123", 1,
"1.23", 0);
3209 test_sh(
".123", 10,
"1230000000", 0);
3210 test_sh(
".123", 14,
"12300000000000", 0);
3211 test_sh(
"000.000", 1000,
"0", 0);
3212 test_sh(
"000.", 1000,
"0", 0);
3213 test_sh(
".000", 1000,
"0", 0);
3214 test_sh(
"1", 1000,
"1", 2);
3215 test_sh(
"123.123", -1,
"12.3123", 0);
3216 test_sh(
"123987654321.123456789000", -1,
"12398765432.1123456789", 0);
3217 test_sh(
"123987654321.123456789000", -2,
"1239876543.21123456789", 0);
3218 test_sh(
"123987654321.123456789000", -3,
"123987654.321123456789", 0);
3219 test_sh(
"123987654321.123456789000", -8,
"1239.87654321123456789", 0);
3220 test_sh(
"123987654321.123456789000", -9,
"123.987654321123456789", 0);
3221 test_sh(
"123987654321.123456789000", -10,
"12.3987654321123456789", 0);
3222 test_sh(
"123987654321.123456789000", -11,
"1.23987654321123456789", 0);
3223 test_sh(
"123987654321.123456789000", -12,
"0.123987654321123456789", 0);
3224 test_sh(
"123987654321.123456789000", -13,
"0.0123987654321123456789", 0);
3225 test_sh(
"123987654321.123456789000", -14,
"0.00123987654321123456789", 0);
3226 test_sh(
"00000087654321.123456789000", -14,
"0.00000087654321123456789", 0);
3228 test_sh(
"123.123", -2,
"1.23123", 0);
3229 test_sh(
"123.123", -3,
"0.123123", 0);
3230 test_sh(
"123.123", -6,
"0.000123123", 0);
3231 test_sh(
"123.123", -7,
"0.0000123123", 0);
3232 test_sh(
"123.123", -15,
"0.000000000000123123", 0);
3233 test_sh(
"123.123", -16,
"0.000000000000012312", 1);
3234 test_sh(
"123.123", -17,
"0.000000000000001231", 1);
3235 test_sh(
"123.123", -18,
"0.000000000000000123", 1);
3236 test_sh(
"123.123", -19,
"0.000000000000000012", 1);
3237 test_sh(
"123.123", -20,
"0.000000000000000001", 1);
3238 test_sh(
"123.123", -21,
"0", 1);
3239 test_sh(
".000000000123", -1,
"0.0000000000123", 0);
3240 test_sh(
".000000000123", -6,
"0.000000000000000123", 0);
3241 test_sh(
".000000000123", -7,
"0.000000000000000012", 1);
3242 test_sh(
".000000000123", -8,
"0.000000000000000001", 1);
3243 test_sh(
".000000000123", -9,
"0", 1);
3244 test_sh(
".000000000123", 1,
"0.00000000123", 0);
3245 test_sh(
".000000000123", 8,
"0.0123", 0);
3246 test_sh(
".000000000123", 9,
"0.123", 0);
3247 test_sh(
".000000000123", 10,
"1.23", 0);
3248 test_sh(
".000000000123", 17,
"12300000", 0);
3249 test_sh(
".000000000123", 18,
"123000000", 0);
3250 test_sh(
".000000000123", 19,
"1230000000", 0);
3251 test_sh(
".000000000123", 20,
"12300000000", 0);
3252 test_sh(
".000000000123", 21,
"123000000000", 0);
3253 test_sh(
".000000000123", 22,
"1230000000000", 0);
3254 test_sh(
".000000000123", 23,
"12300000000000", 0);
3255 test_sh(
".000000000123", 24,
"123000000000000", 0);
3256 test_sh(
".000000000123", 25,
"1230000000000000", 0);
3257 test_sh(
".000000000123", 26,
"12300000000000000", 0);
3258 test_sh(
".000000000123", 27,
"123000000000000000", 0);
3259 test_sh(
".000000000123", 28,
"0.000000000123", 2);
3260 test_sh(
"123456789.987654321", -1,
"12345678.998765432", 1);
3261 test_sh(
"123456789.987654321", -2,
"1234567.899876543", 1);
3262 test_sh(
"123456789.987654321", -8,
"1.234567900", 1);
3263 test_sh(
"123456789.987654321", -9,
"0.123456789987654321", 0);
3264 test_sh(
"123456789.987654321", -10,
"0.012345678998765432", 1);
3265 test_sh(
"123456789.987654321", -17,
"0.000000001234567900", 1);
3266 test_sh(
"123456789.987654321", -18,
"0.000000000123456790", 1);
3267 test_sh(
"123456789.987654321", -19,
"0.000000000012345679", 1);
3268 test_sh(
"123456789.987654321", -26,
"0.000000000000000001", 1);
3269 test_sh(
"123456789.987654321", -27,
"0", 1);
3270 test_sh(
"123456789.987654321", 1,
"1234567900", 1);
3271 test_sh(
"123456789.987654321", 2,
"12345678999", 1);
3272 test_sh(
"123456789.987654321", 4,
"1234567899877", 1);
3273 test_sh(
"123456789.987654321", 8,
"12345678998765432", 1);
3274 test_sh(
"123456789.987654321", 9,
"123456789987654321", 0);
3275 test_sh(
"123456789.987654321", 10,
"123456789.987654321", 2);
3276 test_sh(
"123456789.987654321", 0,
"123456789.987654321", 0);
3277 a.len=
sizeof(buf1)/
sizeof(dec1);
3279 printf(
"==== decimal_actual_fraction ====\n");
3280 test_fr(
"1.123456789000000000",
"1.123456789");
3281 test_fr(
"1.12345678000000000",
"1.12345678");
3282 test_fr(
"1.1234567000000000",
"1.1234567");
3283 test_fr(
"1.123456000000000",
"1.123456");
3284 test_fr(
"1.12345000000000",
"1.12345");
3285 test_fr(
"1.1234000000000",
"1.1234");
3286 test_fr(
"1.123000000000",
"1.123");
3287 test_fr(
"1.12000000000",
"1.12");
3288 test_fr(
"1.1000000000",
"1.1");
3289 test_fr(
"1.000000000",
"1");
3290 test_fr(
"1.0",
"1");
3291 test_fr(
"10000000000000000000.0",
"10000000000000000000");