~dshrews/drizzle/bugs_626566_637590

« back to all changes in this revision

Viewing changes to drizzled/decimal.cc

  • Committer: lbieber
  • Date: 2010-09-13 00:23:51 UTC
  • mfrom: (1759.1.2 build)
  • Revision ID: lbieber@orisndriz08-20100913002351-meze2278ypvpc6ta
Merge Joe - fix bug 600032 - Rollback to savepoint not handled correctly in transaction log
Merge Tim Martin - Adapted existing code documentation in decimal.cc into doxygen format

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
 
16
/** @file
 
17
 *
 
18
 * @brief  SQL standard-compliant decimal number handling
 
19
 *
 
20
 * @note
 
21
 * This library implements SQL standard "exact numeric" type
 
22
 * and is not at all generic, but rather intentinally crippled to
 
23
 * follow the standard :) 
 
24
 */
 
25
 
16
26
/*
17
27
=======================================================================
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
 
=======================================================================
22
28
  Quoting the standard
23
29
  (SQL:2003, Part 2 Foundations, aka ISO/IEC 9075-2:2003)
24
30
 
182
188
  @param[in]   filler      what char to pad with (ZEROFILL et al.)
183
189
  @param[out]  *str        where to store the resulting string
184
190
 
185
 
  @return error coce
 
191
  @return error code
186
192
    @retval E_DEC_OK
187
193
    @retval E_DEC_TRUNCATED
188
194
    @retval E_DEC_OVERFLOW
218
224
}
219
225
 
220
226
 
221
 
/*
222
 
  Convert from decimal to binary representation
223
 
 
224
 
  SYNOPSIS
225
 
    my_decimal2binary()
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
231
 
 
232
 
  NOTE
 
227
/**
 
228
  @brief  Convert from decimal to binary representation
 
229
 
 
230
  @param[in]   mask        error processing mask
 
231
  @param[in]   d           number for conversion
 
232
  @param[out]  bin         pointer to buffer where to write result
 
233
  @param[in]   prec        overall number of decimal digits
 
234
  @param[in]   scale       number of decimal digits after decimal point
 
235
 
 
236
  @note
233
237
    Before conversion we round number if it need but produce truncation
234
238
    error in this case
235
239
 
236
 
  RETURN
237
 
    E_DEC_OK
238
 
    E_DEC_TRUNCATED
239
 
    E_DEC_OVERFLOW
 
240
  @return error code
 
241
   @retval E_DEC_OK
 
242
   @retval E_DEC_TRUNCATED
 
243
   @retval E_DEC_OVERFLOW
240
244
*/
241
245
 
242
246
int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
259
263
}
260
264
 
261
265
 
262
 
/*
263
 
  Convert string for decimal when string can be in some multibyte charset
264
 
 
265
 
  SYNOPSIS
266
 
    str2my_decimal()
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
272
 
 
273
 
  RESULT
274
 
    E_DEC_OK
275
 
    E_DEC_TRUNCATED
276
 
    E_DEC_OVERFLOW
277
 
    E_DEC_BAD_NUM
278
 
    E_DEC_OOM
 
266
/**
 
267
  @brief Convert string for decimal when string can be in some multibyte charset
 
268
 
 
269
  @param  mask            error processing mask
 
270
  @param  from            string to process
 
271
  @param  length          length of given string
 
272
  @param  charset         charset of given string
 
273
  @param  decimal_value   buffer for result storing
 
274
 
 
275
  @return Error code
 
276
   @retval E_DEC_OK
 
277
   @retval E_DEC_TRUNCATED
 
278
   @retval E_DEC_OVERFLOW
 
279
   @retval E_DEC_BAD_NUM
 
280
   @retval E_DEC_OOM
279
281
*/
280
282
 
281
283
int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
459
461
 
460
462
 
461
463
 
462
 
/*
463
 
  Get maximum value for given precision and scale
 
464
/**
 
465
  @brief  Get maximum value for given precision and scale
464
466
 
465
 
  SYNOPSIS
466
 
    max_decimal()
467
 
    precision/scale - see decimal_bin_size() below
468
 
    to              - decimal where where the result will be stored
 
467
  @param  precision/scale  see decimal_bin_size() below
 
468
  @param  to              decimal where where the result will be stored
469
469
                      to->buf and to->len must be set.
470
470
*/
471
471
 
519
519
}
520
520
 
521
521
 
522
 
/*
523
 
  Count actual length of fraction part (without ending zeroes)
 
522
/**
 
523
 @brief Count actual length of fraction part (without ending zeroes)
524
524
 
525
 
  SYNOPSIS
526
 
    decimal_actual_fraction()
527
 
    from    number for processing
 
525
 @param from    number for processing
528
526
*/
529
527
 
530
528
int decimal_actual_fraction(decimal_t *from)
550
548
}
551
549
 
552
550
 
553
 
/*
554
 
  Convert decimal to its printable string representation
 
551
/**
 
552
 @brief  Convert decimal to its printable string representation
555
553
 
556
 
  SYNOPSIS
557
 
    decimal2string()
558
 
      from            - value to convert
559
 
      to              - points to buffer where string representation
560
 
                        should be stored
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
 
554
 @param  from       value to convert
 
555
 @param  to         points to buffer where string representation
 
556
                    should be stored
 
557
 @param  to_len     in:  size of to buffer
 
558
                    out: length of the actually written string
 
559
 @param  fixed_precision 0 if representation can be variable length and
564
560
                        fixed_decimals will not be checked in this case.
565
561
                        Put number as with fixed point position with this
566
562
                        number of digits (sign counted and decimal point is
567
563
                        counted)
568
 
      fixed_decimals  - number digits after point.
569
 
      filler          - character to fill gaps in case of fixed_precision > 0
 
564
 @param  fixed_decimals  number digits after point.
 
565
 @param  filler          character to fill gaps in case of fixed_precision > 0
570
566
 
571
 
  RETURN VALUE
572
 
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
 
567
 @return error code
 
568
   @retval E_DEC_OK
 
569
   @retval E_DEC_TRUNCATED
 
570
   @retval E_DEC_OVERFLOW
573
571
*/
574
 
 
575
572
int decimal2string(const decimal_t *from, char *to, int *to_len,
576
573
                   int fixed_precision, int fixed_decimals,
577
574
                   char filler)
678
675
}
679
676
 
680
677
 
681
 
/*
682
 
  Return bounds of decimal digits in the number
 
678
/**
 
679
 @brief  Return bounds of decimal digits in the number
683
680
 
684
 
  SYNOPSIS
685
 
    digits_bounds()
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
 
681
 @param  from  decimal number for processing
 
682
 @param  start_result  index (from 0 ) of first decimal digits will
 
683
                       be written by this address
 
684
 @param  end_result   index of position just after last decimal digit
690
685
                     be written by this address
691
686
*/
692
 
 
693
687
static void digits_bounds(decimal_t *from, int *start_result, int *end_result)
694
688
{
695
689
  int start, stop, i;
743
737
}
744
738
 
745
739
 
746
 
/*
747
 
  Left shift for alignment of data in buffer
748
 
 
749
 
  SYNOPSIS
750
 
    do_mini_left_shift()
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())
754
 
 
755
 
  NOTE
756
 
    Result fitting in the buffer should be garanted.
757
 
    'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
 
740
/**
 
741
 @param Left shift for alignment of data in buffer
 
742
 
 
743
 @param  dec     pointer to decimal number which have to be shifted
 
744
 @param  shift   number of decimal digits on which it should be shifted
 
745
 @param  beg     beginning of decimal digits (see digits_bounds())
 
746
 @param  end     end of decimal digits (see digits_bounds())
 
747
 
 
748
 @note
 
749
   Result fitting in the buffer should be garanted.
 
750
   'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
 
751
   
 
752
 @todo  Above note is unclear - is 'garanted' a typo for 'guaranteed'
 
753
 or 'granted'?
758
754
*/
759
 
 
760
755
static void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
761
756
{
762
757
  dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
773
768
}
774
769
 
775
770
 
776
 
/*
777
 
  Right shift for alignment of data in buffer
778
 
 
779
 
  SYNOPSIS
780
 
    do_mini_left_shift()
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())
784
 
 
785
 
  NOTE
 
771
/**
 
772
  @brief Right shift for alignment of data in buffer
 
773
 
 
774
  @param  dec     pointer to decimal number which have to be shifted
 
775
  @param  shift   number of decimal digits on which it should be shifted
 
776
  @param  beg     beginning of decimal digits (see digits_bounds())
 
777
  @param  end     end of decimal digits (see digits_bounds())
 
778
 
 
779
  @note
786
780
    Result fitting in the buffer should be garanted.
787
781
    'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
788
782
*/
789
 
 
790
783
static void do_mini_right_shift(decimal_t *dec, int shift, int beg, int last)
791
784
{
792
785
  dec1 *from= dec->buf + ROUND_UP(last) - 1;
803
796
}
804
797
 
805
798
 
806
 
/*
807
 
  Shift of decimal digits in given number (with rounding if it need)
 
799
/**
 
800
  @brief  Shift of decimal digits in given number (with rounding if it need)
808
801
 
809
 
  SYNOPSIS
810
 
    decimal_shift()
811
 
    dec       number to be shifted
812
 
    shift     number of decimal positions
 
802
  @param  dec       number to be shifted
 
803
  @param  shift     number of decimal positions
813
804
              shift > 0 means shift to left shift
814
805
              shift < 0 meand right shift
815
 
  NOTE
 
806
 
 
807
  @note
816
808
    In fact it is multipling on 10^shift.
817
 
  RETURN
818
 
    E_DEC_OK          OK
819
 
    E_DEC_OVERFLOW    operation lead to overflow, number is untoched
820
 
    E_DEC_TRUNCATED   number was rounded to fit into buffer
 
809
 
 
810
  @return  Error code
 
811
   @retval E_DEC_OK          OK
 
812
   @retval E_DEC_OVERFLOW    operation lead to overflow, number is untoched
 
813
   @retval E_DEC_TRUNCATED   number was rounded to fit into buffer
821
814
*/
822
 
 
823
815
static int decimal_shift(decimal_t *dec, int shift)
824
816
{
825
817
  /* index of first non zero digit (all indexes from 0) */
1007
999
}
1008
1000
 
1009
1001
 
1010
 
/*
1011
 
  Convert string to decimal
 
1002
/**
 
1003
  @brief  Convert string to decimal
1012
1004
 
1013
 
  SYNOPSIS
1014
 
    internal_str2decl()
1015
 
      from    - value to convert. Doesn't have to be \0 terminated!
1016
 
      to      - decimal where where the result will be stored
 
1005
  @param  from    value to convert. Doesn't have to be \0 terminated!
 
1006
  @param  to      decimal where where the result will be stored
1017
1007
                to->buf and to->len must be set.
1018
 
      end     - Pointer to pointer to end of string. Will on return be
 
1008
  @param  end     Pointer to pointer to end of string. Will on return be
1019
1009
                set to the char after the last used character
1020
 
      fixed   - use to->intg, to->frac as limits for input number
 
1010
  @param  fixed   use to->intg, to->frac as limits for input number
1021
1011
 
1022
 
  NOTE
 
1012
  @note
1023
1013
    to->intg and to->frac can be modified even when fixed=1
1024
1014
    (but only decreased, in this case)
1025
1015
 
1026
 
  RETURN VALUE
 
1016
  @return
1027
1017
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_BAD_NUM/E_DEC_OOM
1028
1018
    In case of E_DEC_FATAL_ERROR *to is set to decimal zero
1029
1019
    (to make error handling easier)
1030
1020
*/
1031
 
 
1032
1021
int
1033
1022
internal_str2dec(char *from, decimal_t *to, char **end, bool fixed)
1034
1023
{
1178
1167
}
1179
1168
 
1180
1169
 
1181
 
/*
1182
 
  Convert decimal to double
1183
 
 
1184
 
  SYNOPSIS
1185
 
    decimal2double()
1186
 
      from    - value to convert
1187
 
      to      - result will be stored there
1188
 
 
1189
 
  RETURN VALUE
 
1170
/**
 
1171
  @param Convert decimal to double
 
1172
 
 
1173
  @param[in]   from   value to convert
 
1174
  @param[out]  to     result will be stored there
 
1175
 
 
1176
  @return
1190
1177
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1191
1178
*/
1192
1179
 
1204
1191
  return (rc != E_DEC_OK) ? rc : (error ? E_DEC_OVERFLOW : E_DEC_OK);
1205
1192
}
1206
1193
 
1207
 
/*
1208
 
  Convert double to decimal
1209
 
 
1210
 
  SYNOPSIS
1211
 
    double2decimal()
1212
 
      from    - value to convert
1213
 
      to      - result will be stored there
1214
 
 
1215
 
  RETURN VALUE
 
1194
/**
 
1195
 @param  Convert double to decimal
 
1196
 
 
1197
 @param[in]  from    value to convert
 
1198
 @param[out] to      result will be stored there
 
1199
 
 
1200
 @return
1216
1201
    E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
1217
1202
*/
1218
1203
 
1336
1321
  return E_DEC_OK;
1337
1322
}
1338
1323
 
1339
 
/*
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
1343
 
 
1344
 
  SYNOPSIS
1345
 
    decimal2bin()
1346
 
      from    - value to convert
1347
 
      to      - points to buffer where string representation should be stored
1348
 
      precision/scale - see decimal_bin_size() below
1349
 
 
1350
 
  NOTE
1351
 
    the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1352
 
 
1353
 
  RETURN VALUE
1354
 
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1355
 
 
1356
 
  DESCRIPTION
 
1324
/**
 
1325
 @brief
 
1326
  Convert decimal to its binary fixed-length representation (suitable for
 
1327
  comparing with memcmp)
 
1328
 
1357
1329
    for storage decimal numbers are converted to the "binary" format.
1358
1330
 
1359
1331
    This format has the following properties:
1414
1386
    And for -1234567890.1234 it would be
1415
1387
 
1416
1388
                7E F2 04 37 2D FB 2D
 
1389
 
 
1390
 
 
1391
  @param from      value to convert
 
1392
  @param to        points to buffer where string representation should be stored
 
1393
  @param precision see decimal_bin_size() below
 
1394
  @param frac      see decimal_bin_size() below
 
1395
 
 
1396
  @note
 
1397
    The buffer is assumed to be of the size decimal_bin_size(precision, scale)
 
1398
 
 
1399
  @return
 
1400
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
 
1401
 
1417
1402
*/
1418
1403
int decimal2bin(const decimal_t *from, unsigned char *to, int precision, int frac)
1419
1404
{
1533
1518
  return error;
1534
1519
}
1535
1520
 
1536
 
/*
1537
 
  Restores decimal from its binary fixed-length representation
1538
 
 
1539
 
  SYNOPSIS
1540
 
    bin2decimal()
1541
 
      from    - value to convert
1542
 
      to      - result
1543
 
      precision/scale - see decimal_bin_size() below
1544
 
 
1545
 
  NOTE
 
1521
/**
 
1522
 @brief Restores decimal from its binary fixed-length representation
 
1523
 
 
1524
 @param  from    value to convert
 
1525
 @param  to      result
 
1526
 @param  precision see decimal_bin_size() below
 
1527
 @param  scale     see decimal_bin_size() below
 
1528
 
 
1529
 @note
1546
1530
    see decimal2bin()
1547
1531
    the buffer is assumed to be of the size decimal_bin_size(precision, scale)
1548
1532
 
1549
 
  RETURN VALUE
 
1533
 @return
1550
1534
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
1551
1535
*/
1552
 
 
1553
1536
int bin2decimal(const unsigned char *from, decimal_t *to, int precision, int scale)
1554
1537
{
1555
1538
  int error=E_DEC_OK, intg=precision-scale,
1652
1635
  return(E_DEC_BAD_NUM);
1653
1636
}
1654
1637
 
1655
 
/*
1656
 
  Returns the size of array to hold a binary representation of a decimal
 
1638
/**
 
1639
 @brief  Returns the size of array to hold a binary representation of a decimal
1657
1640
 
1658
 
  RETURN VALUE
1659
 
    size in bytes
 
1641
 @return  Size in bytes
1660
1642
*/
1661
 
 
1662
1643
int decimal_bin_size(int precision, int scale)
1663
1644
{
1664
1645
  int intg=precision-scale,
1670
1651
         frac0*sizeof(dec1)+dig2bytes[frac0x];
1671
1652
}
1672
1653
 
1673
 
/*
1674
 
  Rounds the decimal to "scale" digits
1675
 
 
1676
 
  SYNOPSIS
1677
 
    decimal_round()
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
1682
 
 
1683
 
  NOTES
 
1654
/**
 
1655
 @brief  Rounds the decimal to "scale" digits
 
1656
 
 
1657
 @param from    - decimal to round,
 
1658
 @param to      - result buffer. from==to is allowed
 
1659
 @param scale   - to what position to round. can be negative!
 
1660
 @param mode    - round to nearest even or truncate
 
1661
 
 
1662
 @note
1684
1663
    scale can be negative !
1685
1664
    one TRUNCATED error (line XXX below) isn't treated very logical :(
1686
1665
 
1687
 
  RETURN VALUE
 
1666
 @return
1688
1667
    E_DEC_OK/E_DEC_TRUNCATED
1689
1668
*/
1690
 
 
1691
1669
int
1692
1670
decimal_round(const decimal_t *from, decimal_t *to, int scale,
1693
1671
              decimal_round_mode mode)
1797
1775
  }
1798
1776
  else
1799
1777
  {
1800
 
    /* TODO - fix this code as it won't work for CEILING mode */
 
1778
  /** @todo fix this code as it won't work for CEILING mode */
1801
1779
    int pos=frac0*DIG_PER_DEC1-scale-1;
1802
1780
    assert(frac0+intg0 > 0);
1803
1781
    x=*buf1 / powers10[pos];
2137
2115
  return 1;
2138
2116
}
2139
2117
 
2140
 
/*
2141
 
  multiply two decimals
2142
 
 
2143
 
  SYNOPSIS
2144
 
    decimal_mul()
2145
 
      from1, from2 - factors
2146
 
      to      - product
2147
 
 
2148
 
  RETURN VALUE
 
2118
/**
 
2119
 @brief multiply two decimals
 
2120
 
 
2121
 @param[in]   from1  First factor
 
2122
 @param[in]   from2  Second factor
 
2123
 @param[out]  to     product
 
2124
 
 
2125
 @return
2149
2126
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
2150
2127
 
2151
 
  NOTES
 
2128
 @note
2152
2129
    in this implementation, with sizeof(dec1)=4 we have DIG_PER_DEC1=9,
2153
2130
    and 63-digit number will take only 7 dec1 words (basically a 7-digit
2154
2131
    "base 999999999" number).  Thus there's no need in fast multiplication
2264
2241
  return error;
2265
2242
}
2266
2243
 
2267
 
/*
 
2244
/**
2268
2245
  naive division algorithm (Knuth's Algorithm D in 4.3.1) -
2269
2246
  it's ok for short numbers
2270
2247
  also we're using alloca() to allocate a temporary buffer
2271
2248
 
2272
 
  XXX if this library is to be used with huge numbers of thousands of
 
2249
  @todo
 
2250
  If this library is to be used with huge numbers of thousands of
2273
2251
  digits, fast division must be implemented and alloca should be
2274
2252
  changed to malloc (or at least fallback to malloc if alloca() fails)
2275
2253
  but then, decimal_mul() should be rewritten too :(
2516
2494
  return error;
2517
2495
}
2518
2496
 
2519
 
/*
2520
 
  division of two decimals
2521
 
 
2522
 
  SYNOPSIS
2523
 
    decimal_div()
2524
 
      from1   - dividend
2525
 
      from2   - divisor
2526
 
      to      - quotient
2527
 
 
2528
 
  RETURN VALUE
 
2497
/**
 
2498
 @brief  division of two decimals
 
2499
 
 
2500
 @param[in]  from1   dividend
 
2501
 @param[in]  from2   divisor
 
2502
 @param[out] to      quotient
 
2503
 
 
2504
 @return
2529
2505
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2530
2506
 
2531
 
  NOTES
 
2507
 @note
2532
2508
    see do_div_mod()
2533
2509
*/
2534
 
 
2535
2510
int
2536
2511
decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
2537
2512
{
2538
2513
  return do_div_mod(from1, from2, to, 0, scale_incr);
2539
2514
}
2540
2515
 
2541
 
/*
2542
 
  modulus
2543
 
 
2544
 
  SYNOPSIS
2545
 
    decimal_mod()
2546
 
      from1   - dividend
2547
 
      from2   - divisor
2548
 
      to      - modulus
2549
 
 
2550
 
  RETURN VALUE
 
2516
/**
 
2517
 @brief modulus
 
2518
 
 
2519
 the modulus R in    R = M mod N
 
2520
 
 
2521
 is defined as
 
2522
 
 
2523
 0 <= |R| < |M|
 
2524
 sign R == sign M
 
2525
 R = M - k*N, where k is integer
 
2526
 
 
2527
 thus, there's no requirement for M or N to be integers
 
2528
 
 
2529
 
 
2530
 @param from1   dividend
 
2531
 @param from2   divisor
 
2532
 @param to      modulus
 
2533
 
 
2534
 @return
2551
2535
    E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
2552
2536
 
2553
 
  NOTES
 
2537
 @note
2554
2538
    see do_div_mod()
2555
2539
 
2556
 
  DESCRIPTION
2557
 
    the modulus R in    R = M mod N
2558
 
 
2559
 
   is defined as
2560
 
 
2561
 
     0 <= |R| < |M|
2562
 
     sign R == sign M
2563
 
     R = M - k*N, where k is integer
2564
 
 
2565
 
   thus, there's no requirement for M or N to be integers
2566
2540
*/
2567
 
 
2568
2541
int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
2569
2542
{
2570
2543
  return do_div_mod(from1, from2, 0, to, 0);