1 : /* compare.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 : /* Compare two bc numbers. Return value is 0 if equal, -1 if N1 is less
43 : than N2 and +1 if N1 is greater than N2. If USE_SIGN is false, just
44 : compare the magnitudes. */
45 :
46 : int
47 : _bc_do_compare (n1, n2, use_sign, ignore_last)
48 : bc_num n1, n2;
49 : int use_sign;
50 : int ignore_last;
51 28 : {
52 : char *n1ptr, *n2ptr;
53 : int count;
54 :
55 : /* First, compare signs. */
56 28 : if (use_sign && n1->n_sign != n2->n_sign)
57 : {
58 2 : if (n1->n_sign == PLUS)
59 0 : return (1); /* Positive N1 > Negative N2 */
60 : else
61 2 : return (-1); /* Negative N1 < Positive N1 */
62 : }
63 :
64 : /* Now compare the magnitude. */
65 26 : if (n1->n_len != n2->n_len)
66 : {
67 6 : if (n1->n_len > n2->n_len)
68 : {
69 : /* Magnitude of n1 > n2. */
70 4 : if (!use_sign || n1->n_sign == PLUS)
71 4 : return (1);
72 : else
73 0 : return (-1);
74 : }
75 : else
76 : {
77 : /* Magnitude of n1 < n2. */
78 2 : if (!use_sign || n1->n_sign == PLUS)
79 2 : return (-1);
80 : else
81 0 : return (1);
82 : }
83 : }
84 :
85 : /* If we get here, they have the same number of integer digits.
86 : check the integer part and the equal length part of the fraction. */
87 20 : count = n1->n_len + MIN (n1->n_scale, n2->n_scale);
88 20 : n1ptr = n1->n_value;
89 20 : n2ptr = n2->n_value;
90 :
91 125 : while ((count > 0) && (*n1ptr == *n2ptr))
92 : {
93 85 : n1ptr++;
94 85 : n2ptr++;
95 85 : count--;
96 : }
97 20 : if (ignore_last && count == 1 && n1->n_scale == n2->n_scale)
98 0 : return (0);
99 20 : if (count != 0)
100 : {
101 15 : if (*n1ptr > *n2ptr)
102 : {
103 : /* Magnitude of n1 > n2. */
104 5 : if (!use_sign || n1->n_sign == PLUS)
105 5 : return (1);
106 : else
107 0 : return (-1);
108 : }
109 : else
110 : {
111 : /* Magnitude of n1 < n2. */
112 10 : if (!use_sign || n1->n_sign == PLUS)
113 10 : return (-1);
114 : else
115 0 : return (1);
116 : }
117 : }
118 :
119 : /* They are equal up to the last part of the equal part of the fraction. */
120 5 : if (n1->n_scale != n2->n_scale)
121 : {
122 2 : if (n1->n_scale > n2->n_scale)
123 : {
124 4 : for (count = n1->n_scale-n2->n_scale; count>0; count--)
125 3 : if (*n1ptr++ != 0)
126 : {
127 : /* Magnitude of n1 > n2. */
128 1 : if (!use_sign || n1->n_sign == PLUS)
129 1 : return (1);
130 : else
131 0 : return (-1);
132 : }
133 : }
134 : else
135 : {
136 0 : for (count = n2->n_scale-n1->n_scale; count>0; count--)
137 0 : if (*n2ptr++ != 0)
138 : {
139 : /* Magnitude of n1 < n2. */
140 0 : if (!use_sign || n1->n_sign == PLUS)
141 0 : return (-1);
142 : else
143 0 : return (1);
144 : }
145 : }
146 : }
147 :
148 : /* They must be equal! */
149 4 : return (0);
150 : }
151 :
152 :
153 : /* This is the "user callable" routine to compare numbers N1 and N2. */
154 :
155 : int
156 : bc_compare (n1, n2)
157 : bc_num n1, n2;
158 9 : {
159 9 : return _bc_do_compare (n1, n2, TRUE, FALSE);
160 : }
161 :
|