1 : /* divmod.c: bcmath library file. */
2 : /*
3 : Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
4 : Copyright (C) 2000 Philip A. Nelson
5 :
6 : This library is free software; you can redistribute it and/or
7 : modify it under the terms of the GNU Lesser General Public
8 : License as published by the Free Software Foundation; either
9 : version 2 of the License, or (at your option) any later version.
10 :
11 : This library is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : Lesser General Public License for more details. (COPYING.LIB)
15 :
16 : You should have received a copy of the GNU Lesser General Public
17 : License along with this library; if not, write to:
18 :
19 : The Free Software Foundation, Inc.
20 : 59 Temple Place, Suite 330
21 : Boston, MA 02111-1307 USA.
22 :
23 : You may contact the author by:
24 : e-mail: philnelson@acm.org
25 : us-mail: Philip A. Nelson
26 : Computer Science Department, 9062
27 : Western Washington University
28 : Bellingham, WA 98226-9062
29 :
30 : *************************************************************************/
31 :
32 : #include <config.h>
33 : #include <stdio.h>
34 : #include <assert.h>
35 : #include <stdlib.h>
36 : #include <ctype.h>
37 : #include <stdarg.h>
38 : #include "bcmath.h"
39 : #include "private.h"
40 :
41 :
42 : /* Division *and* modulo for numbers. This computes both NUM1 / NUM2 and
43 : NUM1 % NUM2 and puts the results in QUOT and REM, except that if QUOT
44 : is NULL then that store will be omitted.
45 : */
46 :
47 : int
48 : bc_divmod (bc_num num1, bc_num num2, bc_num *quot, bc_num *rem, int scale TSRMLS_DC)
49 3 : {
50 3 : bc_num quotient = NULL;
51 : bc_num temp;
52 : int rscale;
53 :
54 : /* Check for correct numbers. */
55 3 : if (bc_is_zero (num2 TSRMLS_CC)) return -1;
56 :
57 : /* Calculate final scale. */
58 3 : rscale = MAX (num1->n_scale, num2->n_scale+scale);
59 3 : bc_init_num(&temp TSRMLS_CC);
60 :
61 : /* Calculate it. */
62 3 : bc_divide (num1, num2, &temp, scale TSRMLS_CC);
63 3 : if (quot)
64 0 : quotient = bc_copy_num (temp);
65 3 : bc_multiply (temp, num2, &temp, rscale TSRMLS_CC);
66 3 : bc_sub (num1, temp, rem, rscale);
67 3 : bc_free_num (&temp);
68 :
69 3 : if (quot)
70 : {
71 0 : bc_free_num (quot);
72 0 : *quot = quotient;
73 : }
74 :
75 3 : return 0; /* Everything is OK. */
76 : }
77 :
78 :
79 : /* Modulo for numbers. This computes NUM1 % NUM2 and puts the
80 : result in RESULT. */
81 :
82 : int
83 : bc_modulo (bc_num num1, bc_num num2, bc_num *result, int scale TSRMLS_DC)
84 3 : {
85 3 : return bc_divmod (num1, num2, NULL, result, scale TSRMLS_CC);
86 : }
87 :
|