12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
18
* @brief SQL standard-compliant decimal number handling
21
* This library implements SQL standard "exact numeric" type
22
* and is not at all generic, but rather intentinally crippled to
23
* follow the standard :)
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
27
17
=======================================================================
18
NOTE: this library implements SQL standard "exact numeric" type
19
and is not at all generic, but rather intentinally crippled to
20
follow the standard :)
21
=======================================================================
28
22
Quoting the standard
29
23
(SQL:2003, Part 2 Foundations, aka ISO/IEC 9075-2:2003)
209
204
fixed_prec will be 0, and my_decimal_string_length() will be called
210
205
instead to calculate the required size of the buffer.
212
int length= (int)(fixed_prec
213
? (uint32_t)(fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
214
: (uint32_t)my_decimal_string_length(d));
207
int length= (fixed_prec
208
? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
209
: my_decimal_string_length(d));
216
211
if (str->alloc(length))
217
212
return check_result(mask, E_DEC_OOM);
227
@brief Convert from decimal to binary representation
229
@param[in] mask error processing mask
230
@param[in] d number for conversion
231
@param[out] bin pointer to buffer where to write result
232
@param[in] prec overall number of decimal digits
233
@param[in] scale number of decimal digits after decimal point
222
Convert from decimal to binary representation
226
mask error processing mask
227
d number for conversion
228
bin pointer to buffer where to write result
229
prec overall number of decimal digits
230
scale number of decimal digits after decimal point
236
233
Before conversion we round number if it need but produce truncation
237
234
error in this case
241
@retval E_DEC_TRUNCATED
242
@retval E_DEC_OVERFLOW
245
242
int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
266
@brief Convert string for decimal when string can be in some multibyte charset
268
@param mask error processing mask
269
@param from string to process
270
@param length length of given string
271
@param charset charset of given string
272
@param decimal_value buffer for result storing
276
@retval E_DEC_TRUNCATED
277
@retval E_DEC_OVERFLOW
278
@retval E_DEC_BAD_NUM
263
Convert string for decimal when string can be in some multibyte charset
267
mask error processing mask
268
from string to process
269
length length of given string
270
charset charset of given string
271
decimal_value buffer for result storing
282
281
int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
363
362
#define DIG_MASK 100000000
364
363
#define DIG_BASE 1000000000
365
364
#define DIG_MAX (DIG_BASE-1)
368
inline static T round_up(const T &x)
370
return (x+DIG_PER_DEC1-1)/DIG_PER_DEC1;
365
#define ROUND_UP(X) (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
373
366
static const dec1 powers10[DIG_PER_DEC1+1]={
374
367
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
375
368
static const int dig2bytes[DIG_PER_DEC1+1]={0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
378
371
999900000, 999990000, 999999000,
379
372
999999900, 999999990 };
382
375
#define sanity(d) assert((d)->len > 0)
384
377
#define sanity(d) assert((d)->len >0 && ((d)->buf[0] | \
385
378
(d)->buf[(d)->len-1] | 1))
388
inline static void fix_intg_frac_error(const int len, int &intg1, int &frac1, int &error)
390
if (unlikely(intg1+frac1 > len))
392
if (unlikely(intg1 > len))
396
error=E_DEC_OVERFLOW;
401
error=E_DEC_TRUNCATED;
408
/* assume carry <= 1 */
409
inline static void add(dec1 &to, const dec1 &from1, const dec1& from2, dec1 &carry)
411
dec1 a=from1+from2+carry;
413
if ((carry= (a >= DIG_BASE))) /* no division here! */
418
inline static void add2(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
420
dec2 a=dec2(from1)+from2+carry;
421
if ((carry= (a >= DIG_BASE)))
423
if (unlikely(a >= DIG_BASE))
432
inline static void sub(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
434
dec1 a=from1-from2-carry;
435
if ((carry= (a < 0)))
441
inline static void sub2(dec1 &to, const dec1 &from1, const dec1 &from2, dec1 &carry)
443
dec1 a=from1-from2-carry;
444
if ((carry= (a < 0)))
381
#define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error) \
384
if (unlikely(intg1+frac1 > (len))) \
386
if (unlikely(intg1 > (len))) \
390
error=E_DEC_OVERFLOW; \
395
error=E_DEC_TRUNCATED; \
402
#define ADD(to, from1, from2, carry) /* assume carry <= 1 */ \
405
dec1 a=(from1)+(from2)+(carry); \
406
assert((carry) <= 1); \
407
if (((carry)= a >= DIG_BASE)) /* no division here! */ \
412
#define ADD2(to, from1, from2, carry) \
415
dec2 a=((dec2)(from1))+(from2)+(carry); \
416
if (((carry)= a >= DIG_BASE)) \
418
if (unlikely(a >= DIG_BASE)) \
426
#define SUB(to, from1, from2, carry) /* to=from1-from2 */ \
429
dec1 a=(from1)-(from2)-(carry); \
430
if (((carry)= a < 0)) \
435
#define SUB2(to, from1, from2, carry) /* to=from1-from2 */ \
438
dec1 a=(from1)-(from2)-(carry); \
439
if (((carry)= a < 0)) \
441
if (unlikely(a < 0)) \
455
@brief Get maximum value for given precision and scale
457
@param precision/scale see decimal_bin_size() below
458
@param to decimal where where the result will be stored
450
Swap the contents of two variables.
452
#define swap_variables(TYPE, a, b) \
463
Get maximum value for given precision and scale
467
precision/scale - see decimal_bin_size() below
468
to - decimal where where the result will be stored
459
469
to->buf and to->len must be set.
513
@brief Count actual length of fraction part (without ending zeroes)
523
Count actual length of fraction part (without ending zeroes)
515
@param from number for processing
526
decimal_actual_fraction()
527
from number for processing
518
530
int decimal_actual_fraction(decimal_t *from)
520
532
int frac= from->frac, i;
521
dec1 *buf0= from->buf + round_up(from->intg) + round_up(frac) - 1;
533
dec1 *buf0= from->buf + ROUND_UP(from->intg) + ROUND_UP(frac) - 1;
542
@brief Convert decimal to its printable string representation
554
Convert decimal to its printable string representation
544
@param from value to convert
545
@param to points to buffer where string representation
547
@param to_len in: size of to buffer
548
out: length of the actually written string
549
@param fixed_precision 0 if representation can be variable length and
558
from - value to convert
559
to - points to buffer where string representation
561
*to_len - in: size of to buffer
562
out: length of the actually written string
563
fixed_precision - 0 if representation can be variable length and
550
564
fixed_decimals will not be checked in this case.
551
565
Put number as with fixed point position with this
552
566
number of digits (sign counted and decimal point is
554
@param fixed_decimals number digits after point.
555
@param filler character to fill gaps in case of fixed_precision > 0
568
fixed_decimals - number digits after point.
569
filler - character to fill gaps in case of fixed_precision > 0
559
@retval E_DEC_TRUNCATED
560
@retval E_DEC_OVERFLOW
572
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
562
575
int decimal2string(const decimal_t *from, char *to, int *to_len,
563
576
int fixed_precision, int fixed_decimals,
669
@brief Return bounds of decimal digits in the number
682
Return bounds of decimal digits in the number
671
@param from decimal number for processing
672
@param start_result index (from 0 ) of first decimal digits will
673
be written by this address
674
@param end_result index of position just after last decimal digit
686
from - decimal number for processing
687
start_result - index (from 0 ) of first decimal digits will
688
be written by this address
689
end_result - index of position just after last decimal digit
675
690
be written by this address
677
693
static void digits_bounds(decimal_t *from, int *start_result, int *end_result)
679
695
int start, stop, i;
680
696
dec1 *buf_beg= from->buf;
681
dec1 *end= from->buf + round_up(from->intg) + round_up(from->frac);
697
dec1 *end= from->buf + ROUND_UP(from->intg) + ROUND_UP(from->frac);
682
698
dec1 *buf_end= end - 1;
684
700
/* find non-zero digit from number begining */
731
@param Left shift for alignment of data in buffer
733
@param dec pointer to decimal number which have to be shifted
734
@param shift number of decimal digits on which it should be shifted
735
@param beg beginning of decimal digits (see digits_bounds())
736
@param end end of decimal digits (see digits_bounds())
739
Result fitting in the buffer should be garanted.
740
'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
742
@todo Above note is unclear - is 'garanted' a typo for 'guaranteed'
747
Left shift for alignment of data in buffer
751
dec pointer to decimal number which have to be shifted
752
shift number of decimal digits on which it should be shifted
753
beg/end bounds of decimal digits (see digits_bounds())
756
Result fitting in the buffer should be garanted.
757
'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
745
760
static void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
747
dec1 *from= dec->buf + round_up(beg + 1) - 1;
748
dec1 *end= dec->buf + round_up(last) - 1;
762
dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
763
dec1 *end= dec->buf + ROUND_UP(last) - 1;
749
764
int c_shift= DIG_PER_DEC1 - shift;
750
765
assert(from >= dec->buf);
751
766
assert(end < dec->buf + dec->len);
762
@brief Right shift for alignment of data in buffer
764
@param dec pointer to decimal number which have to be shifted
765
@param shift number of decimal digits on which it should be shifted
766
@param beg beginning of decimal digits (see digits_bounds())
767
@param end end of decimal digits (see digits_bounds())
777
Right shift for alignment of data in buffer
781
dec pointer to decimal number which have to be shifted
782
shift number of decimal digits on which it should be shifted
783
beg/end bounds of decimal digits (see digits_bounds())
770
786
Result fitting in the buffer should be garanted.
771
787
'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
773
790
static void do_mini_right_shift(decimal_t *dec, int shift, int beg, int last)
775
dec1 *from= dec->buf + round_up(last) - 1;
776
dec1 *end= dec->buf + round_up(beg + 1) - 1;
792
dec1 *from= dec->buf + ROUND_UP(last) - 1;
793
dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1;
777
794
int c_shift= DIG_PER_DEC1 - shift;
778
795
assert(from < dec->buf + dec->len);
779
796
assert(end >= dec->buf);
790
@brief Shift of decimal digits in given number (with rounding if it need)
807
Shift of decimal digits in given number (with rounding if it need)
792
@param dec number to be shifted
793
@param shift number of decimal positions
811
dec number to be shifted
812
shift number of decimal positions
794
813
shift > 0 means shift to left shift
795
814
shift < 0 meand right shift
798
816
In fact it is multipling on 10^shift.
819
E_DEC_OVERFLOW operation lead to overflow, number is untoched
820
E_DEC_TRUNCATED number was rounded to fit into buffer
802
@retval E_DEC_OVERFLOW operation lead to overflow, number is untoched
803
@retval E_DEC_TRUNCATED number was rounded to fit into buffer
805
823
static int decimal_shift(decimal_t *dec, int shift)
807
825
/* index of first non zero digit (all indexes from 0) */
945
963
d_shift= (1 - new_front) / DIG_PER_DEC1;
946
to= dec->buf + round_up(end) - 1 + d_shift;
947
barier= dec->buf + round_up(beg + 1) - 1 + d_shift;
964
to= dec->buf + ROUND_UP(end) - 1 + d_shift;
965
barier= dec->buf + ROUND_UP(beg + 1) - 1 + d_shift;
948
966
assert(to < dec->buf + dec->len);
949
967
assert(barier - d_shift >= dec->buf);
950
968
for(; to >= barier; to--)
993
@brief Convert string to decimal
1011
Convert string to decimal
995
@param from value to convert. Doesn't have to be \0 terminated!
996
@param to decimal where where the result will be stored
1015
from - value to convert. Doesn't have to be \0 terminated!
1016
to - decimal where where the result will be stored
997
1017
to->buf and to->len must be set.
998
@param end Pointer to pointer to end of string. Will on return be
1018
end - Pointer to pointer to end of string. Will on return be
999
1019
set to the char after the last used character
1000
@param fixed use to->intg, to->frac as limits for input number
1020
fixed - use to->intg, to->frac as limits for input number
1003
1023
to->intg and to->frac can be modified even when fixed=1
1004
1024
(but only decreased, in this case)
1007
1027
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_BAD_NUM/E_DEC_OOM
1008
1028
In case of E_DEC_FATAL_ERROR *to is set to decimal zero
1009
1029
(to make error handling easier)
1012
1033
internal_str2dec(char *from, decimal_t *to, char **end, bool fixed)
1311
1336
return E_DEC_OK;
1316
Convert decimal to its binary fixed-length representation (suitable for
1317
comparing with memcmp)
1340
Convert decimal to its binary fixed-length representation
1341
two representations of the same length can be compared with memcmp
1342
with the correct -1/0/+1 result
1346
from - value to convert
1347
to - points to buffer where string representation should be stored
1348
precision/scale - see decimal_bin_size() below
1351
the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1354
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1319
1357
for storage decimal numbers are converted to the "binary" format.
1321
1359
This format has the following properties:
1376
1414
And for -1234567890.1234 it would be
1378
1416
7E F2 04 37 2D FB 2D
1381
@param from value to convert
1382
@param to points to buffer where string representation should be stored
1383
@param precision see decimal_bin_size() below
1384
@param frac see decimal_bin_size() below
1387
The buffer is assumed to be of the size decimal_bin_size(precision, scale)
1390
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1393
1418
int decimal2bin(const decimal_t *from, unsigned char *to, int precision, int frac)
1512
@brief Restores decimal from its binary fixed-length representation
1514
@param from value to convert
1516
@param precision see decimal_bin_size() below
1517
@param scale see decimal_bin_size() below
1537
Restores decimal from its binary fixed-length representation
1541
from - value to convert
1543
precision/scale - see decimal_bin_size() below
1520
1546
see decimal2bin()
1521
1547
the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1524
1550
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1526
1553
int bin2decimal(const unsigned char *from, decimal_t *to, int precision, int scale)
1528
1555
int error=E_DEC_OK, intg=precision-scale,
1641
1670
frac0*sizeof(dec1)+dig2bytes[frac0x];
1645
@brief Rounds the decimal to "scale" digits
1647
@param from - decimal to round,
1648
@param to - result buffer. from==to is allowed
1649
@param scale - to what position to round. can be negative!
1650
@param mode - round to nearest even or truncate
1674
Rounds the decimal to "scale" digits
1678
from - decimal to round,
1679
to - result buffer. from==to is allowed
1680
scale - to what position to round. can be negative!
1681
mode - round to nearest even or truncate
1653
1684
scale can be negative !
1654
1685
one TRUNCATED error (line XXX below) isn't treated very logical :(
1657
1688
E_DEC_OK/E_DEC_TRUNCATED
1660
1692
decimal_round(const decimal_t *from, decimal_t *to, int scale,
1661
1693
decimal_round_mode mode)
1663
int frac0=scale>0 ? round_up(scale) : scale/DIG_PER_DEC1,
1664
frac1=round_up(from->frac), round_digit= 0,
1665
intg0=round_up(from->intg), error=E_DEC_OK, len=to->len,
1666
intg1=round_up(from->intg +
1695
int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
1696
frac1=ROUND_UP(from->frac), round_digit= 0,
1697
intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len,
1698
intg1=ROUND_UP(from->intg +
1667
1699
(((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX)));
1668
1700
dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
1852
1884
static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1854
int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
1855
frac1=round_up(from1->frac), frac2=round_up(from2->frac),
1886
int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1887
frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
1856
1888
frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
1857
1889
dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
1868
1900
to->buf[0]=0; /* safety */
1871
fix_intg_frac_error(to->len, intg0, frac0, error);
1903
FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
1872
1904
if (unlikely(error == E_DEC_OVERFLOW))
1874
1906
max_decimal(to->len * DIG_PER_DEC1, 0, to);
1933
1965
if to==0, return -1/0/+1 - the result of the comparison */
1934
1966
static int do_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1936
int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
1937
frac1=round_up(from1->frac), frac2=round_up(from2->frac);
1968
int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1969
frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
1938
1970
int frac0=max(frac1, frac2), error;
1939
1971
dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
2000
2032
/* ensure that always from1 > from2 (and intg1 >= intg2) */
2004
swap(start1, start2);
2035
swap_variables(const decimal_t *,from1, from2);
2036
swap_variables(dec1 *,start1, start2);
2037
swap_variables(int,intg1,intg2);
2038
swap_variables(int,frac1,frac2);
2007
2039
to->sign= 1 - to->sign;
2010
fix_intg_frac_error(to->len, intg1, frac0, error);
2042
FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
2011
2043
buf0=to->buf+intg1+frac0;
2013
2045
to->frac=max(from1->frac, from2->frac);
2042
2074
while (buf2 > stop2)
2044
sub(*--buf0, 0, *--buf2, carry);
2076
SUB(*--buf0, 0, *--buf2, carry);
2048
2080
/* part 2 - cmin(frac) ... intg2 */
2049
2081
while (buf2 > start2)
2051
sub(*--buf0, *--buf1, *--buf2, carry);
2083
SUB(*--buf0, *--buf1, *--buf2, carry);
2054
2086
/* part 3 - intg2 ... intg1 */
2055
2087
while (carry && buf1 > start1)
2057
sub(*--buf0, *--buf1, 0, carry);
2089
SUB(*--buf0, *--buf1, 0, carry);
2060
2092
while (buf1 > start1)
2098
2130
int decimal_is_zero(const decimal_t *from)
2100
2132
dec1 *buf1=from->buf,
2101
*end=buf1+round_up(from->intg)+round_up(from->frac);
2133
*end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2102
2134
while (buf1 < end)
2109
@brief multiply two decimals
2111
@param[in] from1 First factor
2112
@param[in] from2 Second factor
2113
@param[out] to product
2141
multiply two decimals
2145
from1, from2 - factors
2116
2149
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
2119
2152
in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
2120
2153
and 63-digit number will take only 7 dec1 words (basically a 7-digit
2121
2154
"base 999999999" number). Thus there's no need in fast multiplication
2128
2161
int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2130
int intg1=round_up(from1->intg), intg2=round_up(from2->intg),
2131
frac1=round_up(from1->frac), frac2=round_up(from2->frac),
2132
intg0=round_up(from1->intg+from2->intg),
2163
int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
2164
frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
2165
intg0=ROUND_UP(from1->intg+from2->intg),
2133
2166
frac0=frac1+frac2, error, i, j, d_to_move;
2134
2167
dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0,
2135
2168
*start2, *stop2, *stop1, *start0, carry;
2179
2212
dec2 p= ((dec2)*buf1) * ((dec2)*buf2);
2180
2213
hi=(dec1)(p/DIG_BASE);
2181
2214
lo=(dec1)(p-((dec2)hi)*DIG_BASE);
2182
add2(*buf0, *buf0, lo, carry);
2215
ADD2(*buf0, *buf0, lo, carry);
2187
2220
if (buf0 < to->buf)
2188
2221
return E_DEC_OVERFLOW;
2189
add2(*buf0, *buf0, 0, carry);
2222
ADD2(*buf0, *buf0, 0, carry);
2191
2224
for (buf0--; carry; buf0--)
2193
2226
if (buf0 < to->buf)
2194
2227
return E_DEC_OVERFLOW;
2195
add(*buf0, *buf0, 0, carry);
2228
ADD(*buf0, *buf0, 0, carry);
2235
2268
naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2236
2269
it's ok for short numbers
2237
2270
also we're using alloca() to allocate a temporary buffer
2240
If this library is to be used with huge numbers of thousands of
2272
XXX if this library is to be used with huge numbers of thousands of
2241
2273
digits, fast division must be implemented and alloca should be
2242
2274
changed to malloc (or at least fallback to malloc if alloca() fails)
2243
2275
but then, decimal_mul() should be rewritten too :(
2245
2277
static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2246
2278
decimal_t *to, decimal_t *mod, int scale_incr)
2248
int frac1=round_up(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2249
frac2=round_up(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2280
int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2281
frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2250
2282
error= 0, i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2251
2283
dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2252
2284
*start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
2315
2347
N2 is in the buf2, has prec2 digits. Scales are frac1 and
2316
2348
frac2 accordingly.
2317
2349
Thus, the result will have
2318
frac = round_up(frac1+frac2+scale_incr)
2350
frac = ROUND_UP(frac1+frac2+scale_incr)
2320
2352
intg = (prec1-frac1) - (prec2-frac2) + 1
2321
2353
prec = intg+frac
2323
frac0=round_up(frac1+frac2+scale_incr);
2324
fix_intg_frac_error(to->len, intg0, frac0, error);
2355
frac0=ROUND_UP(frac1+frac2+scale_incr);
2356
FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
2325
2357
to->sign=from1->sign != from2->sign;
2326
2358
to->intg=intg0*DIG_PER_DEC1;
2327
2359
to->frac=frac0*DIG_PER_DEC1;
2488
@brief division of two decimals
2490
@param[in] from1 dividend
2491
@param[in] from2 divisor
2492
@param[out] to quotient
2520
division of two decimals
2495
2529
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2498
2532
see do_div_mod()
2501
2536
decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
2503
2538
return do_div_mod(from1, from2, to, 0, scale_incr);
2509
the modulus R in R = M mod N
2515
R = M - k*N, where k is integer
2517
thus, there's no requirement for M or N to be integers
2520
@param from1 dividend
2521
@param from2 divisor
2525
2551
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2528
2554
see do_div_mod()
2557
the modulus R in R = M mod N
2563
R = M - k*N, where k is integer
2565
thus, there's no requirement for M or N to be integers
2531
2568
int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2533
2570
return do_div_mod(from1, from2, 0, to, 0);
2547
2584
printf("/* intg=%d, frac=%d, sign=%d, buf[]={", d->intg, d->frac, d->sign);
2548
for (i=0; i < round_up(d->frac)+round_up(d->intg)-1; i++)
2585
for (i=0; i < ROUND_UP(d->frac)+ROUND_UP(d->intg)-1; i++)
2549
2586
printf("%09d, ", d->buf[i]);
2550
2587
printf("%09d} */ ", d->buf[i]);