mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
@@ -45,6 +45,18 @@ bcmath_compare_result _bc_do_compare(bc_num n1, bc_num n2, size_t scale, bool us
|
||||
|
||||
/* First, compare signs. */
|
||||
if (use_sign && n1->n_sign != n2->n_sign) {
|
||||
/*
|
||||
* scale and n->n_scale differ only in Number objects.
|
||||
* This happens when explicitly specify the scale in a Number method.
|
||||
*/
|
||||
if ((n1->n_scale > scale || n2->n_scale > scale) &&
|
||||
n1->n_len == 1 && n2->n_len == 1 &&
|
||||
n1->n_value[0] == 0 && n2->n_value[0] == 0 &&
|
||||
bc_is_zero_for_scale(n1, scale) && bc_is_zero_for_scale(n2, scale)
|
||||
) {
|
||||
/* e.g. 0.00 <=> -0.00 */
|
||||
return BCMATH_EQUAL;
|
||||
}
|
||||
if (n1->n_sign == PLUS) {
|
||||
/* Positive N1 > Negative N2 */
|
||||
return BCMATH_LEFT_GREATER;
|
||||
|
||||
@@ -173,6 +173,15 @@ bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, siz
|
||||
if (str_scale > scale && !auto_scale) {
|
||||
fractional_end -= str_scale - scale;
|
||||
str_scale = scale;
|
||||
|
||||
/*
|
||||
* e.g. 123.0001 with scale 2 -> 123.00
|
||||
* So, remove the trailing 0 again.
|
||||
*/
|
||||
if (str_scale > 0) {
|
||||
const char *fractional_new_end = bc_skip_zero_reverse(fractional_end, fractional_ptr);
|
||||
str_scale -= fractional_new_end - fractional_end;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (full_scale) {
|
||||
|
||||
@@ -13,6 +13,7 @@ echo bccomp("-2.29", "2.3", "2") . "\n";
|
||||
echo bccomp("2.29", "-2.3", "2") . "\n";
|
||||
echo bccomp("-2.29", "-2.3", "1") . "\n";
|
||||
echo bccomp("-2.29", "0", "1") . "\n";
|
||||
echo bccomp("0.001", "-0.001", "1") . "\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
0
|
||||
@@ -22,3 +23,4 @@ echo bccomp("-2.29", "0", "1") . "\n";
|
||||
1
|
||||
1
|
||||
-1
|
||||
0
|
||||
|
||||
71
ext/bcmath/tests/number/methods/compare_near_zero.phpt
Normal file
71
ext/bcmath/tests/number/methods/compare_near_zero.phpt
Normal file
@@ -0,0 +1,71 @@
|
||||
--TEST--
|
||||
BcMath\Number compare() with scale
|
||||
--EXTENSIONS--
|
||||
bcmath
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$values1 = [
|
||||
new BcMath\Number('0.001'),
|
||||
new BcMath\Number('-0.001'),
|
||||
];
|
||||
|
||||
$values2 = [
|
||||
0,
|
||||
-0,
|
||||
'0.0011',
|
||||
'-0.0011',
|
||||
];
|
||||
|
||||
$value1 = new BcMath\Number('0.001');
|
||||
|
||||
$scales = [0, 2, 3, 4];
|
||||
|
||||
foreach ($scales as $scale) {
|
||||
echo "========== scale is {$scale} ==========\n";
|
||||
foreach ($values1 as $value1) {
|
||||
foreach ($values2 as $value2) {
|
||||
$output = str_pad("{$value1} <=> {$value2}: ", 20, ' ', STR_PAD_LEFT);
|
||||
$output .= str_pad((string) $value1->compare($value2, $scale), 2, ' ', STR_PAD_LEFT);
|
||||
echo "{$output}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
========== scale is 0 ==========
|
||||
0.001 <=> 0: 0
|
||||
0.001 <=> 0: 0
|
||||
0.001 <=> 0.0011: 0
|
||||
0.001 <=> -0.0011: 0
|
||||
-0.001 <=> 0: 0
|
||||
-0.001 <=> 0: 0
|
||||
-0.001 <=> 0.0011: 0
|
||||
-0.001 <=> -0.0011: 0
|
||||
========== scale is 2 ==========
|
||||
0.001 <=> 0: 0
|
||||
0.001 <=> 0: 0
|
||||
0.001 <=> 0.0011: 0
|
||||
0.001 <=> -0.0011: 0
|
||||
-0.001 <=> 0: 0
|
||||
-0.001 <=> 0: 0
|
||||
-0.001 <=> 0.0011: 0
|
||||
-0.001 <=> -0.0011: 0
|
||||
========== scale is 3 ==========
|
||||
0.001 <=> 0: 1
|
||||
0.001 <=> 0: 1
|
||||
0.001 <=> 0.0011: 0
|
||||
0.001 <=> -0.0011: 1
|
||||
-0.001 <=> 0: -1
|
||||
-0.001 <=> 0: -1
|
||||
-0.001 <=> 0.0011: -1
|
||||
-0.001 <=> -0.0011: 0
|
||||
========== scale is 4 ==========
|
||||
0.001 <=> 0: 1
|
||||
0.001 <=> 0: 1
|
||||
0.001 <=> 0.0011: -1
|
||||
0.001 <=> -0.0011: 1
|
||||
-0.001 <=> 0: -1
|
||||
-0.001 <=> 0: -1
|
||||
-0.001 <=> 0.0011: -1
|
||||
-0.001 <=> -0.0011: 1
|
||||
Reference in New Issue
Block a user