ext/bcmath: Fixed bcdiv() div by one (#15629)

Fixed the incorrect scale that should be used when dividing by 1, that is,
comparing the divisor and 1 to confirm equality.

Additionally, have increased the number of test cases for bcdiv_by_pow_10.phpt.
This commit is contained in:
Saki Takamachi 2024-08-30 09:33:17 +09:00 committed by GitHub
parent 09d5b7102a
commit e8fe7e4f52
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 404 additions and 81 deletions

View file

@ -344,7 +344,7 @@ bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale)
} }
/* If divisor is 1 / -1, the quotient's n_value is equal to numerator's n_value. */ /* If divisor is 1 / -1, the quotient's n_value is equal to numerator's n_value. */
if (_bc_do_compare(divisor, BCG(_one_), scale, false) == BCMATH_EQUAL) { if (_bc_do_compare(divisor, BCG(_one_), divisor->n_scale, false) == BCMATH_EQUAL) {
size_t quot_scale = MIN(numerator->n_scale, scale); size_t quot_scale = MIN(numerator->n_scale, scale);
*quot = bc_new_num_nonzeroed(numerator->n_len, quot_scale); *quot = bc_new_num_nonzeroed(numerator->n_len, quot_scale);
char *qptr = (*quot)->n_value; char *qptr = (*quot)->n_value;

View file

@ -0,0 +1,98 @@
--TEST--
bcdiv() function div by one
--EXTENSIONS--
bcmath
--INI--
bcmath.scale=0
--FILE--
<?php
$dividend_cases = ['100', '-100'];
$divisor_cases = ['1.010', '1.01', '1.1', '1', '-1.010', '-1.01', '-1.1', '-1'];
$scale_cases = [0, 1, 2, 3];
foreach ($scale_cases as $scale) {
echo "scale: {$scale}\n";
foreach ($divisor_cases as $divisor) {
foreach ($dividend_cases as $dividend) {
$dividend_label = str_pad($dividend, 4, ' ', STR_PAD_LEFT);
$divisor_label = str_pad($divisor, 6, ' ', STR_PAD_LEFT);
$quot = bcdiv($dividend, $divisor, $scale);
$quot_label = str_pad($quot, $scale + 2 + ($scale ? 1 : 0), ' ', STR_PAD_LEFT);
echo $dividend_label, ' / ', $divisor_label, ' = ', $quot_label, "\n";
}
}
echo "\n";
}
?>
--EXPECT--
scale: 0
100 / 1.010 = 99
-100 / 1.010 = -99
100 / 1.01 = 99
-100 / 1.01 = -99
100 / 1.1 = 90
-100 / 1.1 = -90
100 / 1 = 100
-100 / 1 = -100
100 / -1.010 = -99
-100 / -1.010 = 99
100 / -1.01 = -99
-100 / -1.01 = 99
100 / -1.1 = -90
-100 / -1.1 = 90
100 / -1 = -100
-100 / -1 = 100
scale: 1
100 / 1.010 = 99.0
-100 / 1.010 = -99.0
100 / 1.01 = 99.0
-100 / 1.01 = -99.0
100 / 1.1 = 90.9
-100 / 1.1 = -90.9
100 / 1 = 100.0
-100 / 1 = -100.0
100 / -1.010 = -99.0
-100 / -1.010 = 99.0
100 / -1.01 = -99.0
-100 / -1.01 = 99.0
100 / -1.1 = -90.9
-100 / -1.1 = 90.9
100 / -1 = -100.0
-100 / -1 = 100.0
scale: 2
100 / 1.010 = 99.00
-100 / 1.010 = -99.00
100 / 1.01 = 99.00
-100 / 1.01 = -99.00
100 / 1.1 = 90.90
-100 / 1.1 = -90.90
100 / 1 = 100.00
-100 / 1 = -100.00
100 / -1.010 = -99.00
-100 / -1.010 = 99.00
100 / -1.01 = -99.00
-100 / -1.01 = 99.00
100 / -1.1 = -90.90
-100 / -1.1 = 90.90
100 / -1 = -100.00
-100 / -1 = 100.00
scale: 3
100 / 1.010 = 99.009
-100 / 1.010 = -99.009
100 / 1.01 = 99.009
-100 / 1.01 = -99.009
100 / 1.1 = 90.909
-100 / 1.1 = -90.909
100 / 1 = 100.000
-100 / 1 = -100.000
100 / -1.010 = -99.009
-100 / -1.010 = 99.009
100 / -1.01 = -99.009
-100 / -1.01 = 99.009
100 / -1.1 = -90.909
-100 / -1.1 = 90.909
100 / -1 = -100.000
-100 / -1 = 100.000

View file

@ -6,18 +6,18 @@ bcmath
bcmath.scale=0 bcmath.scale=0
--FILE-- --FILE--
<?php <?php
$dividend_cases = ['0.012345', '0.12345', '1.2345', '12.345', '123.45']; $dividend_cases = ['0.012345', '0.12345', '1.2345', '12.345', '123.45', '-0.012345', '-0.12345', '-1.2345', '-12.345', '-123.45'];
$divisor_cases = ['0.01', '0.1', '1', '10', '100']; $divisor_cases = ['0.01', '0.1', '1', '10', '100', '-0.01', '-0.1', '-1', '-10', '-100'];
$scale_cases = [0, 3, 5]; $scale_cases = [0, 3, 5];
foreach ($scale_cases as $scale) { foreach ($scale_cases as $scale) {
echo "scale: {$scale}\n"; echo "scale: {$scale}\n";
foreach ($divisor_cases as $divisor) { foreach ($divisor_cases as $divisor) {
foreach ($dividend_cases as $dividend) { foreach ($dividend_cases as $dividend) {
$dividend_label = str_pad($dividend, 8, ' ', STR_PAD_LEFT); $dividend_label = str_pad($dividend, 9, ' ', STR_PAD_LEFT);
$divisor_label = str_pad($divisor, 4, ' ', STR_PAD_LEFT); $divisor_label = str_pad($divisor, 5, ' ', STR_PAD_LEFT);
$quot = bcdiv($dividend, $divisor, $scale); $quot = bcdiv($dividend, $divisor, $scale);
$quot_label = str_pad($quot, $scale + 5 + ($scale ? 1 : 0), ' ', STR_PAD_LEFT); $quot_label = str_pad($quot, $scale + 7 + ($scale ? 1 : 0), ' ', STR_PAD_LEFT);
echo $dividend_label, ' / ', $divisor_label, ' = ', $quot_label, "\n"; echo $dividend_label, ' / ', $divisor_label, ' = ', $quot_label, "\n";
} }
} }
@ -31,26 +31,101 @@ scale: 0
1.2345 / 0.01 = 123 1.2345 / 0.01 = 123
12.345 / 0.01 = 1234 12.345 / 0.01 = 1234
123.45 / 0.01 = 12345 123.45 / 0.01 = 12345
-0.012345 / 0.01 = -1
-0.12345 / 0.01 = -12
-1.2345 / 0.01 = -123
-12.345 / 0.01 = -1234
-123.45 / 0.01 = -12345
0.012345 / 0.1 = 0 0.012345 / 0.1 = 0
0.12345 / 0.1 = 1 0.12345 / 0.1 = 1
1.2345 / 0.1 = 12 1.2345 / 0.1 = 12
12.345 / 0.1 = 123 12.345 / 0.1 = 123
123.45 / 0.1 = 1234 123.45 / 0.1 = 1234
-0.012345 / 0.1 = 0
-0.12345 / 0.1 = -1
-1.2345 / 0.1 = -12
-12.345 / 0.1 = -123
-123.45 / 0.1 = -1234
0.012345 / 1 = 0 0.012345 / 1 = 0
0.12345 / 1 = 0 0.12345 / 1 = 0
1.2345 / 1 = 1 1.2345 / 1 = 1
12.345 / 1 = 12 12.345 / 1 = 12
123.45 / 1 = 123 123.45 / 1 = 123
-0.012345 / 1 = 0
-0.12345 / 1 = 0
-1.2345 / 1 = -1
-12.345 / 1 = -12
-123.45 / 1 = -123
0.012345 / 10 = 0 0.012345 / 10 = 0
0.12345 / 10 = 0 0.12345 / 10 = 0
1.2345 / 10 = 0 1.2345 / 10 = 0
12.345 / 10 = 1 12.345 / 10 = 1
123.45 / 10 = 12 123.45 / 10 = 12
-0.012345 / 10 = 0
-0.12345 / 10 = 0
-1.2345 / 10 = 0
-12.345 / 10 = -1
-123.45 / 10 = -12
0.012345 / 100 = 0 0.012345 / 100 = 0
0.12345 / 100 = 0 0.12345 / 100 = 0
1.2345 / 100 = 0 1.2345 / 100 = 0
12.345 / 100 = 0 12.345 / 100 = 0
123.45 / 100 = 1 123.45 / 100 = 1
-0.012345 / 100 = 0
-0.12345 / 100 = 0
-1.2345 / 100 = 0
-12.345 / 100 = 0
-123.45 / 100 = -1
0.012345 / -0.01 = -1
0.12345 / -0.01 = -12
1.2345 / -0.01 = -123
12.345 / -0.01 = -1234
123.45 / -0.01 = -12345
-0.012345 / -0.01 = 1
-0.12345 / -0.01 = 12
-1.2345 / -0.01 = 123
-12.345 / -0.01 = 1234
-123.45 / -0.01 = 12345
0.012345 / -0.1 = 0
0.12345 / -0.1 = -1
1.2345 / -0.1 = -12
12.345 / -0.1 = -123
123.45 / -0.1 = -1234
-0.012345 / -0.1 = 0
-0.12345 / -0.1 = 1
-1.2345 / -0.1 = 12
-12.345 / -0.1 = 123
-123.45 / -0.1 = 1234
0.012345 / -1 = 0
0.12345 / -1 = 0
1.2345 / -1 = -1
12.345 / -1 = -12
123.45 / -1 = -123
-0.012345 / -1 = 0
-0.12345 / -1 = 0
-1.2345 / -1 = 1
-12.345 / -1 = 12
-123.45 / -1 = 123
0.012345 / -10 = 0
0.12345 / -10 = 0
1.2345 / -10 = 0
12.345 / -10 = -1
123.45 / -10 = -12
-0.012345 / -10 = 0
-0.12345 / -10 = 0
-1.2345 / -10 = 0
-12.345 / -10 = 1
-123.45 / -10 = 12
0.012345 / -100 = 0
0.12345 / -100 = 0
1.2345 / -100 = 0
12.345 / -100 = 0
123.45 / -100 = -1
-0.012345 / -100 = 0
-0.12345 / -100 = 0
-1.2345 / -100 = 0
-12.345 / -100 = 0
-123.45 / -100 = 1
scale: 3 scale: 3
0.012345 / 0.01 = 1.234 0.012345 / 0.01 = 1.234
@ -58,26 +133,101 @@ scale: 3
1.2345 / 0.01 = 123.450 1.2345 / 0.01 = 123.450
12.345 / 0.01 = 1234.500 12.345 / 0.01 = 1234.500
123.45 / 0.01 = 12345.000 123.45 / 0.01 = 12345.000
-0.012345 / 0.01 = -1.234
-0.12345 / 0.01 = -12.345
-1.2345 / 0.01 = -123.450
-12.345 / 0.01 = -1234.500
-123.45 / 0.01 = -12345.000
0.012345 / 0.1 = 0.123 0.012345 / 0.1 = 0.123
0.12345 / 0.1 = 1.234 0.12345 / 0.1 = 1.234
1.2345 / 0.1 = 12.345 1.2345 / 0.1 = 12.345
12.345 / 0.1 = 123.450 12.345 / 0.1 = 123.450
123.45 / 0.1 = 1234.500 123.45 / 0.1 = 1234.500
-0.012345 / 0.1 = -0.123
-0.12345 / 0.1 = -1.234
-1.2345 / 0.1 = -12.345
-12.345 / 0.1 = -123.450
-123.45 / 0.1 = -1234.500
0.012345 / 1 = 0.012 0.012345 / 1 = 0.012
0.12345 / 1 = 0.123 0.12345 / 1 = 0.123
1.2345 / 1 = 1.234 1.2345 / 1 = 1.234
12.345 / 1 = 12.345 12.345 / 1 = 12.345
123.45 / 1 = 123.450 123.45 / 1 = 123.450
-0.012345 / 1 = -0.012
-0.12345 / 1 = -0.123
-1.2345 / 1 = -1.234
-12.345 / 1 = -12.345
-123.45 / 1 = -123.450
0.012345 / 10 = 0.001 0.012345 / 10 = 0.001
0.12345 / 10 = 0.012 0.12345 / 10 = 0.012
1.2345 / 10 = 0.123 1.2345 / 10 = 0.123
12.345 / 10 = 1.234 12.345 / 10 = 1.234
123.45 / 10 = 12.345 123.45 / 10 = 12.345
-0.012345 / 10 = -0.001
-0.12345 / 10 = -0.012
-1.2345 / 10 = -0.123
-12.345 / 10 = -1.234
-123.45 / 10 = -12.345
0.012345 / 100 = 0.000 0.012345 / 100 = 0.000
0.12345 / 100 = 0.001 0.12345 / 100 = 0.001
1.2345 / 100 = 0.012 1.2345 / 100 = 0.012
12.345 / 100 = 0.123 12.345 / 100 = 0.123
123.45 / 100 = 1.234 123.45 / 100 = 1.234
-0.012345 / 100 = 0.000
-0.12345 / 100 = -0.001
-1.2345 / 100 = -0.012
-12.345 / 100 = -0.123
-123.45 / 100 = -1.234
0.012345 / -0.01 = -1.234
0.12345 / -0.01 = -12.345
1.2345 / -0.01 = -123.450
12.345 / -0.01 = -1234.500
123.45 / -0.01 = -12345.000
-0.012345 / -0.01 = 1.234
-0.12345 / -0.01 = 12.345
-1.2345 / -0.01 = 123.450
-12.345 / -0.01 = 1234.500
-123.45 / -0.01 = 12345.000
0.012345 / -0.1 = -0.123
0.12345 / -0.1 = -1.234
1.2345 / -0.1 = -12.345
12.345 / -0.1 = -123.450
123.45 / -0.1 = -1234.500
-0.012345 / -0.1 = 0.123
-0.12345 / -0.1 = 1.234
-1.2345 / -0.1 = 12.345
-12.345 / -0.1 = 123.450
-123.45 / -0.1 = 1234.500
0.012345 / -1 = -0.012
0.12345 / -1 = -0.123
1.2345 / -1 = -1.234
12.345 / -1 = -12.345
123.45 / -1 = -123.450
-0.012345 / -1 = 0.012
-0.12345 / -1 = 0.123
-1.2345 / -1 = 1.234
-12.345 / -1 = 12.345
-123.45 / -1 = 123.450
0.012345 / -10 = -0.001
0.12345 / -10 = -0.012
1.2345 / -10 = -0.123
12.345 / -10 = -1.234
123.45 / -10 = -12.345
-0.012345 / -10 = 0.001
-0.12345 / -10 = 0.012
-1.2345 / -10 = 0.123
-12.345 / -10 = 1.234
-123.45 / -10 = 12.345
0.012345 / -100 = 0.000
0.12345 / -100 = -0.001
1.2345 / -100 = -0.012
12.345 / -100 = -0.123
123.45 / -100 = -1.234
-0.012345 / -100 = 0.000
-0.12345 / -100 = 0.001
-1.2345 / -100 = 0.012
-12.345 / -100 = 0.123
-123.45 / -100 = 1.234
scale: 5 scale: 5
0.012345 / 0.01 = 1.23450 0.012345 / 0.01 = 1.23450
@ -85,23 +235,98 @@ scale: 5
1.2345 / 0.01 = 123.45000 1.2345 / 0.01 = 123.45000
12.345 / 0.01 = 1234.50000 12.345 / 0.01 = 1234.50000
123.45 / 0.01 = 12345.00000 123.45 / 0.01 = 12345.00000
-0.012345 / 0.01 = -1.23450
-0.12345 / 0.01 = -12.34500
-1.2345 / 0.01 = -123.45000
-12.345 / 0.01 = -1234.50000
-123.45 / 0.01 = -12345.00000
0.012345 / 0.1 = 0.12345 0.012345 / 0.1 = 0.12345
0.12345 / 0.1 = 1.23450 0.12345 / 0.1 = 1.23450
1.2345 / 0.1 = 12.34500 1.2345 / 0.1 = 12.34500
12.345 / 0.1 = 123.45000 12.345 / 0.1 = 123.45000
123.45 / 0.1 = 1234.50000 123.45 / 0.1 = 1234.50000
-0.012345 / 0.1 = -0.12345
-0.12345 / 0.1 = -1.23450
-1.2345 / 0.1 = -12.34500
-12.345 / 0.1 = -123.45000
-123.45 / 0.1 = -1234.50000
0.012345 / 1 = 0.01234 0.012345 / 1 = 0.01234
0.12345 / 1 = 0.12345 0.12345 / 1 = 0.12345
1.2345 / 1 = 1.23450 1.2345 / 1 = 1.23450
12.345 / 1 = 12.34500 12.345 / 1 = 12.34500
123.45 / 1 = 123.45000 123.45 / 1 = 123.45000
-0.012345 / 1 = -0.01234
-0.12345 / 1 = -0.12345
-1.2345 / 1 = -1.23450
-12.345 / 1 = -12.34500
-123.45 / 1 = -123.45000
0.012345 / 10 = 0.00123 0.012345 / 10 = 0.00123
0.12345 / 10 = 0.01234 0.12345 / 10 = 0.01234
1.2345 / 10 = 0.12345 1.2345 / 10 = 0.12345
12.345 / 10 = 1.23450 12.345 / 10 = 1.23450
123.45 / 10 = 12.34500 123.45 / 10 = 12.34500
-0.012345 / 10 = -0.00123
-0.12345 / 10 = -0.01234
-1.2345 / 10 = -0.12345
-12.345 / 10 = -1.23450
-123.45 / 10 = -12.34500
0.012345 / 100 = 0.00012 0.012345 / 100 = 0.00012
0.12345 / 100 = 0.00123 0.12345 / 100 = 0.00123
1.2345 / 100 = 0.01234 1.2345 / 100 = 0.01234
12.345 / 100 = 0.12345 12.345 / 100 = 0.12345
123.45 / 100 = 1.23450 123.45 / 100 = 1.23450
-0.012345 / 100 = -0.00012
-0.12345 / 100 = -0.00123
-1.2345 / 100 = -0.01234
-12.345 / 100 = -0.12345
-123.45 / 100 = -1.23450
0.012345 / -0.01 = -1.23450
0.12345 / -0.01 = -12.34500
1.2345 / -0.01 = -123.45000
12.345 / -0.01 = -1234.50000
123.45 / -0.01 = -12345.00000
-0.012345 / -0.01 = 1.23450
-0.12345 / -0.01 = 12.34500
-1.2345 / -0.01 = 123.45000
-12.345 / -0.01 = 1234.50000
-123.45 / -0.01 = 12345.00000
0.012345 / -0.1 = -0.12345
0.12345 / -0.1 = -1.23450
1.2345 / -0.1 = -12.34500
12.345 / -0.1 = -123.45000
123.45 / -0.1 = -1234.50000
-0.012345 / -0.1 = 0.12345
-0.12345 / -0.1 = 1.23450
-1.2345 / -0.1 = 12.34500
-12.345 / -0.1 = 123.45000
-123.45 / -0.1 = 1234.50000
0.012345 / -1 = -0.01234
0.12345 / -1 = -0.12345
1.2345 / -1 = -1.23450
12.345 / -1 = -12.34500
123.45 / -1 = -123.45000
-0.012345 / -1 = 0.01234
-0.12345 / -1 = 0.12345
-1.2345 / -1 = 1.23450
-12.345 / -1 = 12.34500
-123.45 / -1 = 123.45000
0.012345 / -10 = -0.00123
0.12345 / -10 = -0.01234
1.2345 / -10 = -0.12345
12.345 / -10 = -1.23450
123.45 / -10 = -12.34500
-0.012345 / -10 = 0.00123
-0.12345 / -10 = 0.01234
-1.2345 / -10 = 0.12345
-12.345 / -10 = 1.23450
-123.45 / -10 = 12.34500
0.012345 / -100 = -0.00012
0.12345 / -100 = -0.00123
1.2345 / -100 = -0.01234
12.345 / -100 = -0.12345
123.45 / -100 = -1.23450
-0.012345 / -100 = 0.00012
-0.12345 / -100 = 0.00123
-1.2345 / -100 = 0.01234
-12.345 / -100 = 0.12345
-123.45 / -100 = 1.23450