@@ -251,58 +251,39 @@ static inline void bc_standard_div(
251251}
252252
253253static void bc_do_div (
254- const char * numerator , size_t numerator_readable_len , size_t numerator_bottom_extension ,
255- const char * divisor , size_t divisor_len , bc_num * quot , size_t quot_len
254+ const char * numerator , size_t numerator_size , size_t numerator_readable_size ,
255+ const char * divisor , size_t divisor_size ,
256+ bc_num * quot , size_t quot_size
256257) {
257- size_t divisor_arr_size = (divisor_len + BC_VECTOR_SIZE - 1 ) / BC_VECTOR_SIZE ;
258- size_t numerator_arr_size = (numerator_readable_len + numerator_bottom_extension + BC_VECTOR_SIZE - 1 ) / BC_VECTOR_SIZE ;
258+ size_t numerator_arr_size = (numerator_size + BC_VECTOR_SIZE - 1 ) / BC_VECTOR_SIZE ;
259+ size_t divisor_arr_size = (divisor_size + BC_VECTOR_SIZE - 1 ) / BC_VECTOR_SIZE ;
259260 size_t quot_arr_size = numerator_arr_size - divisor_arr_size + 1 ;
260- size_t quot_real_arr_size = MIN (quot_arr_size , (quot_len + BC_VECTOR_SIZE - 1 ) / BC_VECTOR_SIZE );
261+ size_t quot_real_arr_size = MIN (quot_arr_size , (quot_size + BC_VECTOR_SIZE - 1 ) / BC_VECTOR_SIZE );
261262
262263 BC_VECTOR * numerator_vectors = safe_emalloc (numerator_arr_size + divisor_arr_size + quot_arr_size , sizeof (BC_VECTOR ), 0 );
263264 BC_VECTOR * divisor_vectors = numerator_vectors + numerator_arr_size ;
264265 BC_VECTOR * quot_vectors = divisor_vectors + divisor_arr_size ;
265266
266- /* Fill with zeros and convert as many vector elements as needed */
267- size_t numerator_vector_count = 0 ;
268- while (numerator_bottom_extension >= BC_VECTOR_SIZE ) {
269- numerator_vectors [numerator_vector_count ] = 0 ;
270- numerator_bottom_extension -= BC_VECTOR_SIZE ;
271- numerator_vector_count ++ ;
272- }
273-
274- size_t numerator_bottom_read_len = BC_VECTOR_SIZE - numerator_bottom_extension ;
275-
276- size_t base ;
277- size_t numerator_read = 0 ;
278- if (numerator_bottom_read_len < BC_VECTOR_SIZE ) {
279- numerator_read = MIN (numerator_bottom_read_len , numerator_readable_len );
280- base = BC_POW_10_LUT [numerator_bottom_extension ];
281- numerator_vectors [numerator_vector_count ] = 0 ;
282- for (size_t i = 0 ; i < numerator_read ; i ++ ) {
283- numerator_vectors [numerator_vector_count ] += * numerator * base ;
284- base *= BASE ;
285- numerator -- ;
286- }
287- numerator_vector_count ++ ;
288- }
267+ size_t numerator_extension = numerator_size > numerator_readable_size ? numerator_size - numerator_readable_size : 0 ;
289268
290269 /* Bulk convert numerator and divisor to vectors */
291- if (numerator_readable_len > numerator_read ) {
292- bc_convert_to_vector (numerator_vectors + numerator_vector_count , numerator , numerator_readable_len - numerator_read );
293- }
294- bc_convert_to_vector (divisor_vectors , divisor , divisor_len );
270+ size_t numerator_use_size = numerator_size - numerator_extension ;
271+ const char * numerator_end = numerator + numerator_use_size - 1 ;
272+ bc_convert_to_vector_with_zero_pad (numerator_vectors , numerator_end , numerator_use_size , numerator_extension );
273+
274+ const char * divisor_end = divisor + divisor_size - 1 ;
275+ bc_convert_to_vector (divisor_vectors , divisor_end , divisor_size );
295276
296277 /* Do the division */
297278 if (divisor_arr_size == 1 ) {
298279 bc_fast_div (numerator_vectors , numerator_arr_size , divisor_vectors [0 ], quot_vectors , quot_arr_size );
299280 } else {
300- bc_standard_div (numerator_vectors , numerator_arr_size , divisor_vectors , divisor_arr_size , divisor_len , quot_vectors , quot_arr_size );
281+ bc_standard_div (numerator_vectors , numerator_arr_size , divisor_vectors , divisor_arr_size , divisor_size , quot_vectors , quot_arr_size );
301282 }
302283
303284 /* Convert to bc_num */
304285 char * qptr = (* quot )-> n_value ;
305- char * qend = qptr + quot_len - 1 ;
286+ char * qend = qptr + ( * quot ) -> n_len + ( * quot ) -> n_scale - 1 ;
306287
307288 size_t i ;
308289 for (i = 0 ; i < quot_real_arr_size - 1 ; i ++ ) {
@@ -332,166 +313,115 @@ bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale)
332313 }
333314
334315 bc_free_num (quot );
316+ size_t quot_scale = scale ;
335317
336318 /* If numerator is zero, the quotient is always zero. */
337319 if (bc_is_zero (numerator )) {
338- * quot = bc_copy_num (BCG (_zero_ ));
339- return true;
320+ goto quot_zero ;
340321 }
341322
342323 /* If divisor is 1 / -1, the quotient's n_value is equal to numerator's n_value. */
343324 if (_bc_do_compare (divisor , BCG (_one_ ), divisor -> n_scale , false) == BCMATH_EQUAL ) {
344- size_t quot_scale = MIN (numerator -> n_scale , scale );
325+ quot_scale = MIN (numerator -> n_scale , quot_scale );
345326 * quot = bc_new_num_nonzeroed (numerator -> n_len , quot_scale );
346327 char * qptr = (* quot )-> n_value ;
347328 memcpy (qptr , numerator -> n_value , numerator -> n_len + quot_scale );
348329 (* quot )-> n_sign = numerator -> n_sign == divisor -> n_sign ? PLUS : MINUS ;
349- _bc_rm_leading_zeros (* quot );
350330 return true;
351331 }
352332
353333 char * numeratorptr = numerator -> n_value ;
354- char * numeratorend = numeratorptr + numerator -> n_len + numerator -> n_scale - 1 ;
355- size_t numerator_len = numerator -> n_len ;
356- size_t numerator_scale = numerator -> n_scale ;
334+ size_t numerator_size = numerator -> n_len + quot_scale + divisor -> n_scale ;
357335
358336 char * divisorptr = divisor -> n_value ;
359- char * divisorend = divisorptr + divisor -> n_len + divisor -> n_scale - 1 ;
360- size_t divisor_len = divisor -> n_len ;
361- size_t divisor_scale = divisor -> n_scale ;
362- size_t divisor_int_right_zeros = 0 ;
363-
364- /* remove divisor trailing zeros */
365- while (* divisorend == 0 && divisor_scale > 0 ) {
366- divisorend -- ;
367- divisor_scale -- ;
368- }
369- while (* divisorend == 0 ) {
370- divisorend -- ;
371- divisor_int_right_zeros ++ ;
372- }
337+ size_t divisor_size = divisor -> n_len + divisor -> n_scale ;
373338
374- if (* numeratorptr == 0 && numerator_len == 1 ) {
339+ /* check and remove numerator leading zeros */
340+ size_t numerator_leading_zeros = 0 ;
341+ while (* numeratorptr == 0 ) {
375342 numeratorptr ++ ;
376- numerator_len = 0 ;
343+ numerator_leading_zeros ++ ;
377344 }
378-
379- size_t numerator_top_extension = 0 ;
380- size_t numerator_bottom_extension = 0 ;
381- if (divisor_scale > 0 ) {
382- /*
383- * e.g. divisor_scale = 4
384- * divisor = .0002, to be 2 or divisor = 200.001, to be 200001
385- * numerator = .03, to be 300 or numerator = .000003, to be .03
386- * numerator may become longer than the original data length due to the addition of
387- * trailing zeros in the integer part.
388- */
389- numerator_len += divisor_scale ;
390- numerator_bottom_extension = numerator_scale < divisor_scale ? divisor_scale - numerator_scale : 0 ;
391- numerator_scale = numerator_scale > divisor_scale ? numerator_scale - divisor_scale : 0 ;
392- divisor_len += divisor_scale ;
393- divisor_scale = 0 ;
394- } else if (divisor_int_right_zeros > 0 ) {
395- /*
396- * e.g. divisor_int_right_zeros = 4
397- * divisor = 2000, to be 2
398- * numerator = 30, to be .03 or numerator = 30000, to be 30
399- * Also, numerator may become longer than the original data length due to the addition of
400- * leading zeros in the fractional part.
401- */
402- numerator_top_extension = numerator_len < divisor_int_right_zeros ? divisor_int_right_zeros - numerator_len : 0 ;
403- numerator_len = numerator_len > divisor_int_right_zeros ? numerator_len - divisor_int_right_zeros : 0 ;
404- numerator_scale += divisor_int_right_zeros ;
405- divisor_len -= divisor_int_right_zeros ;
406- divisor_scale = 0 ;
345+ if (numerator_size > numerator_leading_zeros ) {
346+ numerator_size -= numerator_leading_zeros ;
347+ } else {
348+ goto quot_zero ;
407349 }
408350
409- /* remove numerator leading zeros */
410- while (* numeratorptr == 0 && numerator_len > 0 ) {
411- numeratorptr ++ ;
412- numerator_len -- ;
413- }
414- /* remove divisor leading zeros */
351+ /* check and remove divisor leading zeros */
415352 while (* divisorptr == 0 ) {
416353 divisorptr ++ ;
417- divisor_len -- ;
354+ divisor_size -- ;
418355 }
419356
420- /* Considering the scale specification, the quotient is always 0 if this condition is met */
421- if (divisor_len > numerator_len + scale ) {
422- * quot = bc_copy_num (BCG (_zero_ ));
423- return true;
357+ if (divisor_size > numerator_size ) {
358+ goto quot_zero ;
424359 }
425360
426- /* Length of numerator data that can be read */
427- size_t numerator_readable_len = numeratorend - numeratorptr + 1 ;
428-
429- /* set scale to numerator */
430- if (numerator_scale > scale ) {
431- size_t scale_diff = numerator_scale - scale ;
432- if (numerator_bottom_extension > scale_diff ) {
433- numerator_bottom_extension -= scale_diff ;
434- } else {
435- numerator_bottom_extension = 0 ;
436- if (EXPECTED (numerator_readable_len > scale_diff )) {
437- numerator_readable_len -= scale_diff ;
438- numeratorend -= scale_diff ;
439- } else {
440- numerator_readable_len = 0 ;
441- numeratorend = numeratorptr ;
442- }
361+ /* check and remove divisor trailing zeros. The divisor is not 0, so leave only one digit */
362+ size_t divisor_trailing_zeros = 0 ;
363+ for (size_t i = divisor_size - 1 ; i > 0 ; i -- ) {
364+ if (divisorptr [i ] != 0 ) {
365+ break ;
443366 }
444- numerator_top_extension = MIN (numerator_top_extension , scale );
367+ divisor_trailing_zeros ++ ;
368+ }
369+ divisor_size -= divisor_trailing_zeros ;
370+
371+ if (numerator_size > divisor_trailing_zeros ) {
372+ numerator_size -= divisor_trailing_zeros ;
445373 } else {
446- numerator_bottom_extension += scale - numerator_scale ;
374+ goto quot_zero ;
447375 }
448- numerator_scale = scale ;
449376
450- if (divisor_len > numerator_readable_len + numerator_bottom_extension ) {
451- * quot = bc_copy_num (BCG (_zero_ ));
452- return true;
377+ size_t quot_size = numerator_size - divisor_size + 1 ; /* numerator_size >= divisor_size */
378+ if (quot_size > quot_scale ) {
379+ * quot = bc_new_num_nonzeroed (quot_size - quot_scale , quot_scale );
380+ } else {
381+ * quot = bc_new_num_nonzeroed (1 , quot_scale ); /* 1 is for 0 */
453382 }
454383
455- /* If divisor is 1 here, return the result of adjusting the decimal point position of numerator. */
456- if (divisor_len == 1 && * divisorptr == 1 ) {
457- if (numerator_len == 0 ) {
458- numerator_len = 1 ;
459- numerator_top_extension ++ ;
460- }
461- size_t quot_scale = numerator_scale > numerator_bottom_extension ? numerator_scale - numerator_bottom_extension : 0 ;
462- numerator_bottom_extension = numerator_scale < numerator_bottom_extension ? numerator_bottom_extension - numerator_scale : 0 ;
384+ /* Size that can be read from numeratorptr */
385+ size_t numerator_readable_size = numerator -> n_len + numerator -> n_scale - numerator_leading_zeros ;
463386
464- * quot = bc_new_num_nonzeroed (numerator_len , quot_scale );
387+ /* If divisor is 1 here, return the result of adjusting the decimal point position of numerator. */
388+ if (divisor_size == 1 && * divisorptr == 1 ) {
465389 char * qptr = (* quot )-> n_value ;
466- for (size_t i = 0 ; i < numerator_top_extension ; i ++ ) {
390+ if (quot_size <= quot_scale ) {
391+ /* int is 0 */
467392 * qptr ++ = 0 ;
393+ for (size_t i = quot_size ; i < quot_scale ; i ++ ) {
394+ * qptr ++ = 0 ;
395+ }
468396 }
469- memcpy (qptr , numeratorptr , numerator_readable_len );
470- qptr += numerator_readable_len ;
471- for (size_t i = 0 ; i < numerator_bottom_extension ; i ++ ) {
397+ size_t numerator_use_size = quot_size > numerator_readable_size ? numerator_readable_size : quot_size ;
398+ memcpy (qptr , numeratorptr , numerator_use_size );
399+ qptr += numerator_use_size ;
400+ for (size_t i = 0 ; i < quot_size - numerator_use_size ; i ++ ) {
472401 * qptr ++ = 0 ;
473402 }
403+ bc_rm_trailing_zeros (* quot );
474404 (* quot )-> n_sign = numerator -> n_sign == divisor -> n_sign ? PLUS : MINUS ;
475405 return true;
476406 }
477407
478- size_t quot_full_len ;
479- if (divisor_len > numerator_len ) {
480- * quot = bc_new_num_nonzeroed (1 , scale );
481- quot_full_len = 1 + scale ;
482- } else {
483- * quot = bc_new_num_nonzeroed (numerator_len - divisor_len + 1 , scale );
484- quot_full_len = numerator_len - divisor_len + 1 + scale ;
485- }
486-
487408 /* do divide */
488- bc_do_div (numeratorend , numerator_readable_len , numerator_bottom_extension , divisorend , divisor_len , quot , quot_full_len );
409+ bc_do_div (
410+ numeratorptr , numerator_size , numerator_readable_size ,
411+ divisorptr , divisor_size ,
412+ quot , quot_size
413+ );
414+
489415 _bc_rm_leading_zeros (* quot );
490416 if (bc_is_zero (* quot )) {
491- (* quot )-> n_sign = PLUS ;
417+ bc_free_num (quot );
418+ goto quot_zero ;
492419 } else {
493420 (* quot )-> n_sign = numerator -> n_sign == divisor -> n_sign ? PLUS : MINUS ;
494421 }
422+ return true;
495423
424+ quot_zero :
425+ * quot = bc_copy_num (BCG (_zero_ ));
496426 return true;
497427}
0 commit comments