3333#include "private.h"
3434#include <stdbool.h>
3535#include <stddef.h>
36+ #include <string.h>
3637#include "zend_alloc.h"
3738
3839
4344
4445static void _one_mult (unsigned char * num , size_t size , int digit , unsigned char * result )
4546{
46- int carry , value ;
47+ size_t carry , value ;
4748 unsigned char * nptr , * rptr ;
4849
4950 if (digit == 0 ) {
@@ -53,8 +54,8 @@ static void _one_mult(unsigned char *num, size_t size, int digit, unsigned char
5354 memcpy (result , num , size );
5455 } else {
5556 /* Initialize */
56- nptr = (unsigned char * ) (num + size - 1 );
57- rptr = (unsigned char * ) (result + size - 1 );
57+ nptr = (unsigned char * ) (num + size - 1 );
58+ rptr = (unsigned char * ) (result + size - 1 );
5859 carry = 0 ;
5960
6061 while (size -- > 0 ) {
@@ -74,121 +75,113 @@ static void _one_mult(unsigned char *num, size_t size, int digit, unsigned char
7475/* The full division routine. This computes N1 / N2. It returns
7576 true if the division is ok and the result is in QUOT. The number of
7677 digits after the decimal point is SCALE. It returns false if division
77- by zero is tried. The algorithm is found in Knuth Vol 2. p237. */
78+ by zero is tried. The algorithm is found in Knuth Vol 2. p237. */
7879bool bc_divide (bc_num n1 , bc_num n2 , bc_num * quot , int scale )
7980{
8081 bc_num qval ;
8182 unsigned char * num1 , * num2 ;
8283 unsigned char * ptr1 , * ptr2 , * n2ptr , * qptr ;
83- int scale1 , val ;
84- unsigned int len1 , len2 , scale2 , qdigits , extra , count ;
85- unsigned int qdig , qguess , borrow , carry ;
84+ int scale1 , val ;
85+ unsigned int len1 , len2 , scale2 , qdigits , extra , count ;
86+ unsigned int qdig , qguess , borrow , carry ;
8687 unsigned char * mval ;
88+ unsigned int norm ;
8789 bool zero ;
88- unsigned int norm ;
8990
9091 /* Test for divide by zero. */
9192 if (bc_is_zero (n2 )) {
9293 return false;
9394 }
9495
95- /* Test for divide by 1. If it is we must truncate. */
96- if (n2 -> n_scale == 0 ) {
97- if (n2 -> n_len == 1 && * n2 -> n_value == 1 ) {
98- qval = bc_new_num (n1 -> n_len , scale );
99- qval -> n_sign = (n1 -> n_sign == n2 -> n_sign ? PLUS : MINUS );
100- memset (& qval -> n_value [n1 -> n_len ],0 ,scale );
101- memcpy (qval -> n_value , n1 -> n_value , n1 -> n_len + MIN (n1 -> n_scale ,scale ));
102- bc_free_num (quot );
103- * quot = qval ;
104- }
96+ /* Test for divide by 1. If it is we must truncate. */
97+ if (n2 -> n_scale == 0 && n2 -> n_len == 1 && * n2 -> n_value == 1 ) {
98+ qval = bc_new_num (n1 -> n_len , scale );
99+ qval -> n_sign = (n1 -> n_sign == n2 -> n_sign ? PLUS : MINUS );
100+ memset (& qval -> n_value [n1 -> n_len ], 0 , scale );
101+ memcpy (qval -> n_value , n1 -> n_value , n1 -> n_len + MIN (n1 -> n_scale , scale ));
102+ bc_free_num (quot );
103+ * quot = qval ;
105104 }
106105
107106 /* Set up the divide. Move the decimal point on n1 by n2's scale.
108107 Remember, zeros on the end of num2 are wasted effort for dividing. */
109108 scale2 = n2 -> n_scale ;
110- n2ptr = (unsigned char * ) n2 -> n_value + n2 -> n_len + scale2 - 1 ;
111- while ((scale2 > 0 ) && (* n2ptr -- == 0 )) {
109+ n2ptr = (unsigned char * ) n2 -> n_value + n2 -> n_len + scale2 - 1 ;
110+ while ((scale2 > 0 ) && (* n2ptr == 0 )) {
112111 scale2 -- ;
112+ n2ptr -- ;
113113 }
114114
115115 len1 = n1 -> n_len + scale2 ;
116116 scale1 = n1 -> n_scale - scale2 ;
117- if (scale1 < scale ) {
118- extra = scale - scale1 ;
119- } else {
120- extra = 0 ;
121- }
122- num1 = (unsigned char * ) safe_emalloc (1 , n1 -> n_len + n1 -> n_scale , extra + 2 );
123- memset (num1 , 0 , n1 -> n_len + n1 -> n_scale + extra + 2 );
124- memcpy (num1 + 1 , n1 -> n_value , n1 -> n_len + n1 -> n_scale );
117+ extra = MAX (scale - scale1 , 0 );
118+
119+ num1 = (unsigned char * ) safe_emalloc (1 , n1 -> n_len + n1 -> n_scale , extra + 2 );
120+ memset (num1 , 0 , n1 -> n_len + n1 -> n_scale + extra + 2 );
121+ memcpy (num1 + 1 , n1 -> n_value , n1 -> n_len + n1 -> n_scale );
125122
126123 len2 = n2 -> n_len + scale2 ;
127- num2 = (unsigned char * ) safe_emalloc (1 , len2 , 1 );
128- memcpy (num2 , n2 -> n_value , len2 );
129- * (num2 + len2 ) = 0 ;
124+ num2 = (unsigned char * ) safe_emalloc (1 , len2 , 1 );
125+ memcpy (num2 , n2 -> n_value , len2 );
126+ * (num2 + len2 ) = 0 ;
130127 n2ptr = num2 ;
131128 while (* n2ptr == 0 ) {
132129 n2ptr ++ ;
133130 len2 -- ;
134131 }
135132
136133 /* Calculate the number of quotient digits. */
137- if (len2 > len1 + scale ) {
138- qdigits = scale + 1 ;
134+ if (len2 > len1 + scale ) {
135+ qdigits = scale + 1 ;
139136 zero = true;
140137 } else {
141138 zero = false;
142139 if (len2 > len1 ) {
143140 /* One for the zero integer part. */
144- qdigits = scale + 1 ;
141+ qdigits = scale + 1 ;
145142 } else {
146- qdigits = len1 - len2 + scale + 1 ;
143+ qdigits = len1 - len2 + scale + 1 ;
147144 }
148145 }
149146
150147 /* Allocate and zero the storage for the quotient. */
151- qval = bc_new_num (qdigits - scale ,scale );
152- memset (qval -> n_value , 0 , qdigits );
148+ qval = bc_new_num (qdigits - scale , scale );
149+ memset (qval -> n_value , 0 , qdigits );
153150
154151 /* Allocate storage for the temporary storage mval. */
155152 mval = (unsigned char * ) safe_emalloc (1 , len2 , 1 );
156153
157154 /* Now for the full divide algorithm. */
158155 if (!zero ) {
159156 /* Normalize */
160- norm = 10 / ((int )* n2ptr + 1 );
157+ norm = 10 / ((int ) * n2ptr + 1 );
161158 if (norm != 1 ) {
162- _one_mult (num1 , len1 + scale1 + extra + 1 , norm , num1 );
163- _one_mult (n2ptr , len2 , norm , n2ptr );
159+ _one_mult (num1 , len1 + scale1 + extra + 1 , norm , num1 );
160+ _one_mult (n2ptr , len2 , norm , n2ptr );
164161 }
165162
166163 /* Initialize divide loop. */
167164 qdig = 0 ;
168165 if (len2 > len1 ) {
169- qptr = (unsigned char * ) qval -> n_value + len2 - len1 ;
166+ qptr = (unsigned char * ) qval -> n_value + len2 - len1 ;
170167 } else {
171168 qptr = (unsigned char * ) qval -> n_value ;
172169 }
173170
174171 /* Loop */
175- while (qdig <= len1 + scale - len2 ) {
172+ while (qdig <= len1 + scale - len2 ) {
176173 /* Calculate the quotient digit guess. */
177174 if (* n2ptr == num1 [qdig ]) {
178175 qguess = 9 ;
179176 } else {
180- qguess = (num1 [qdig ]* 10 + num1 [qdig + 1 ]) / * n2ptr ;
177+ qguess = (num1 [qdig ] * 10 + num1 [qdig + 1 ]) / * n2ptr ;
181178 }
182179
183180 /* Test qguess. */
184- if (
185- n2ptr [1 ]* qguess > (num1 [qdig ]* 10 + num1 [qdig + 1 ] - * n2ptr * qguess )* 10 + num1 [qdig + 2 ]
186- ) {
181+ if (n2ptr [1 ] * qguess > (num1 [qdig ] * 10 + num1 [qdig + 1 ] - * n2ptr * qguess ) * 10 + num1 [qdig + 2 ]) {
187182 qguess -- ;
188183 /* And again. */
189- if (
190- n2ptr [1 ]* qguess > (num1 [qdig ]* 10 + num1 [qdig + 1 ] - * n2ptr * qguess )* 10 + num1 [qdig + 2 ]
191- ) {
184+ if (n2ptr [1 ] * qguess > (num1 [qdig ] * 10 + num1 [qdig + 1 ] - * n2ptr * qguess ) * 10 + num1 [qdig + 2 ]) {
192185 qguess -- ;
193186 }
194187 }
@@ -197,10 +190,10 @@ bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale)
197190 borrow = 0 ;
198191 if (qguess != 0 ) {
199192 * mval = 0 ;
200- _one_mult (n2ptr , len2 , qguess , mval + 1 );
201- ptr1 = (unsigned char * ) num1 + qdig + len2 ;
202- ptr2 = (unsigned char * ) mval + len2 ;
203- for (count = 0 ; count < len2 + 1 ; count ++ ) {
193+ _one_mult (n2ptr , len2 , qguess , mval + 1 );
194+ ptr1 = (unsigned char * ) num1 + qdig + len2 ;
195+ ptr2 = (unsigned char * ) mval + len2 ;
196+ for (count = 0 ; count < len2 + 1 ; count ++ ) {
204197 val = (int ) * ptr1 - (int ) * ptr2 -- - borrow ;
205198 if (val < 0 ) {
206199 val += 10 ;
@@ -215,8 +208,8 @@ bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale)
215208 /* Test for negative result. */
216209 if (borrow == 1 ) {
217210 qguess -- ;
218- ptr1 = (unsigned char * ) num1 + qdig + len2 ;
219- ptr2 = (unsigned char * ) n2ptr + len2 - 1 ;
211+ ptr1 = (unsigned char * ) num1 + qdig + len2 ;
212+ ptr2 = (unsigned char * ) n2ptr + len2 - 1 ;
220213 carry = 0 ;
221214 for (count = 0 ; count < len2 ; count ++ ) {
222215 val = (int ) * ptr1 + (int ) * ptr2 -- + carry ;
@@ -240,7 +233,7 @@ bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale)
240233 }
241234
242235 /* Clean up and return the number. */
243- qval -> n_sign = ( n1 -> n_sign == n2 -> n_sign ? PLUS : MINUS );
236+ qval -> n_sign = (n1 -> n_sign == n2 -> n_sign ? PLUS : MINUS );
244237 if (bc_is_zero (qval )) {
245238 qval -> n_sign = PLUS ;
246239 }
0 commit comments