@@ -251,58 +251,39 @@ static inline void bc_standard_div(
251
251
}
252
252
253
253
static 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
256
257
) {
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 ;
259
260
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 );
261
262
262
263
BC_VECTOR * numerator_vectors = safe_emalloc (numerator_arr_size + divisor_arr_size + quot_arr_size , sizeof (BC_VECTOR ), 0 );
263
264
BC_VECTOR * divisor_vectors = numerator_vectors + numerator_arr_size ;
264
265
BC_VECTOR * quot_vectors = divisor_vectors + divisor_arr_size ;
265
266
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 ;
289
268
290
269
/* 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 );
295
276
296
277
/* Do the division */
297
278
if (divisor_arr_size == 1 ) {
298
279
bc_fast_div (numerator_vectors , numerator_arr_size , divisor_vectors [0 ], quot_vectors , quot_arr_size );
299
280
} 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 );
301
282
}
302
283
303
284
/* Convert to bc_num */
304
285
char * qptr = (* quot )-> n_value ;
305
- char * qend = qptr + quot_len - 1 ;
286
+ char * qend = qptr + ( * quot ) -> n_len + ( * quot ) -> n_scale - 1 ;
306
287
307
288
size_t i ;
308
289
for (i = 0 ; i < quot_real_arr_size - 1 ; i ++ ) {
@@ -332,166 +313,114 @@ bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale)
332
313
}
333
314
334
315
bc_free_num (quot );
316
+ size_t quot_scale = scale ;
335
317
336
318
/* If numerator is zero, the quotient is always zero. */
337
319
if (bc_is_zero (numerator )) {
338
- * quot = bc_copy_num (BCG (_zero_ ));
339
- return true;
320
+ goto quot_zero ;
340
321
}
341
322
342
323
/* If divisor is 1 / -1, the quotient's n_value is equal to numerator's n_value. */
343
324
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 );
345
326
* quot = bc_new_num_nonzeroed (numerator -> n_len , quot_scale );
346
327
char * qptr = (* quot )-> n_value ;
347
328
memcpy (qptr , numerator -> n_value , numerator -> n_len + quot_scale );
348
329
(* quot )-> n_sign = numerator -> n_sign == divisor -> n_sign ? PLUS : MINUS ;
349
- _bc_rm_leading_zeros (* quot );
350
330
return true;
351
331
}
352
332
353
333
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 ;
357
335
358
336
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 ;
373
338
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 ) {
375
342
numeratorptr ++ ;
376
- numerator_len = 0 ;
343
+ numerator_leading_zeros ++ ;
377
344
}
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 ;
407
349
}
408
350
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 */
415
352
while (* divisorptr == 0 ) {
416
353
divisorptr ++ ;
417
- divisor_len -- ;
354
+ divisor_size -- ;
418
355
}
419
356
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 ;
424
359
}
425
360
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 ;
443
366
}
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 ;
445
373
} else {
446
- numerator_bottom_extension += scale - numerator_scale ;
374
+ goto quot_zero ;
447
375
}
448
- numerator_scale = scale ;
449
376
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
453
382
}
454
383
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 ;
463
386
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 ) {
465
389
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 */
467
392
* qptr ++ = 0 ;
393
+ for (size_t i = quot_size ; i < quot_scale ; i ++ ) {
394
+ * qptr ++ = 0 ;
395
+ }
468
396
}
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 ++ ) {
472
401
* qptr ++ = 0 ;
473
402
}
474
403
(* quot )-> n_sign = numerator -> n_sign == divisor -> n_sign ? PLUS : MINUS ;
475
404
return true;
476
405
}
477
406
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
-
487
407
/* do divide */
488
- bc_do_div (numeratorend , numerator_readable_len , numerator_bottom_extension , divisorend , divisor_len , quot , quot_full_len );
408
+ bc_do_div (
409
+ numeratorptr , numerator_size , numerator_readable_size ,
410
+ divisorptr , divisor_size ,
411
+ quot , quot_size
412
+ );
413
+
489
414
_bc_rm_leading_zeros (* quot );
490
415
if (bc_is_zero (* quot )) {
491
- (* quot )-> n_sign = PLUS ;
416
+ bc_free_num (quot );
417
+ goto quot_zero ;
492
418
} else {
493
419
(* quot )-> n_sign = numerator -> n_sign == divisor -> n_sign ? PLUS : MINUS ;
494
420
}
421
+ return true;
495
422
423
+ quot_zero :
424
+ * quot = bc_copy_num (BCG (_zero_ ));
496
425
return true;
497
426
}
0 commit comments