Skip to content

Commit 38c1b24

Browse files
committed
Extend the maximum precision round can handle by one digit
1 parent 1fa1933 commit 38c1b24

File tree

2 files changed

+108
-3
lines changed

2 files changed

+108
-3
lines changed

ext/standard/math.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,14 @@ PHPAPI double _php_math_round(double value, int places, int mode) {
132132
}
133133

134134
places = places < INT_MIN+1 ? INT_MIN+1 : places;
135-
precision_places = 14 - php_intlog10abs(value);
135+
precision_places = 15 - php_intlog10abs(value);
136136

137137
f1 = php_intpow10(abs(places));
138138

139139
/* If the decimal precision guaranteed by FP arithmetic is higher than
140140
the requested places BUT is small enough to make sure a non-zero value
141141
is returned, pre-round the result to the precision */
142-
if (precision_places > places && precision_places - 15 < places) {
142+
if (precision_places > places && precision_places - 16 < places) {
143143
int64_t use_precision = precision_places < INT_MIN+1 ? INT_MIN+1 : precision_places;
144144

145145
f2 = php_intpow10(abs((int)use_precision));
@@ -166,7 +166,7 @@ PHPAPI double _php_math_round(double value, int places, int mode) {
166166
tmp_value = value / f1;
167167
}
168168
/* This value is beyond our precision, so rounding it is pointless */
169-
if (fabs(tmp_value) >= 1e15) {
169+
if (fabs(tmp_value) >= 1e16) {
170170
return value;
171171
}
172172
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
--TEST--
2+
Feature GH-12143: Extend the maximum precision round can handle by one digit
3+
--FILE--
4+
<?php
5+
echo "HALF_UP, round up\n";
6+
var_dump(round(0.12345678901234565, 16, PHP_ROUND_HALF_UP));
7+
var_dump(round(-0.12345678901234565, 16, PHP_ROUND_HALF_UP));
8+
var_dump(round(12345678901234565, -1, PHP_ROUND_HALF_UP));
9+
var_dump(round(-12345678901234565, -1, PHP_ROUND_HALF_UP));
10+
var_dump(round(0.000000012345678901234565, 23, PHP_ROUND_HALF_UP));
11+
var_dump(round(-0.000000012345678901234565, 23, PHP_ROUND_HALF_UP));
12+
echo "\n";
13+
14+
echo "HALF_UP, not round up\n";
15+
var_dump(round(0.12345678901234564, 16, PHP_ROUND_HALF_UP));
16+
var_dump(round(-0.12345678901234564, 16, PHP_ROUND_HALF_UP));
17+
var_dump(round(12345678901234564, -1, PHP_ROUND_HALF_UP));
18+
var_dump(round(-12345678901234564, -1, PHP_ROUND_HALF_UP));
19+
var_dump(round(0.000000012345678901234564, 23, PHP_ROUND_HALF_UP));
20+
var_dump(round(-0.000000012345678901234564, 23, PHP_ROUND_HALF_UP));
21+
echo "\n";
22+
23+
echo "HALF_DOWN, round up\n";
24+
var_dump(round(0.12345678901234566, 16, PHP_ROUND_HALF_DOWN));
25+
var_dump(round(-0.12345678901234566, 16, PHP_ROUND_HALF_DOWN));
26+
var_dump(round(12345678901234566, -1, PHP_ROUND_HALF_DOWN));
27+
var_dump(round(-12345678901234566, -1, PHP_ROUND_HALF_DOWN));
28+
var_dump(round(0.000000012345678901234566, 23, PHP_ROUND_HALF_DOWN));
29+
var_dump(round(-0.000000012345678901234566, 23, PHP_ROUND_HALF_DOWN));
30+
echo "\n";
31+
32+
echo "HALF_DOWN, not round up\n";
33+
var_dump(round(0.12345678901234565, 16, PHP_ROUND_HALF_DOWN));
34+
var_dump(round(-0.12345678901234565, 16, PHP_ROUND_HALF_DOWN));
35+
var_dump(round(12345678901234565, -1, PHP_ROUND_HALF_DOWN));
36+
var_dump(round(-12345678901234565, -1, PHP_ROUND_HALF_DOWN));
37+
var_dump(round(0.000000012345678901234565, 23, PHP_ROUND_HALF_DOWN));
38+
var_dump(round(-0.000000012345678901234565, 23, PHP_ROUND_HALF_DOWN));
39+
echo "\n";
40+
41+
echo "HALF_EVEN\n";
42+
var_dump(round(0.12345678901234565, 16, PHP_ROUND_HALF_EVEN));
43+
var_dump(round(-0.12345678901234565, 16, PHP_ROUND_HALF_EVEN));
44+
var_dump(round(12345678901234575, -1, PHP_ROUND_HALF_EVEN));
45+
var_dump(round(-12345678901234575, -1, PHP_ROUND_HALF_EVEN));
46+
var_dump(round(0.000000012345678901234525, 23, PHP_ROUND_HALF_EVEN));
47+
var_dump(round(-0.000000012345678901234525, 23, PHP_ROUND_HALF_EVEN));
48+
echo "\n";
49+
50+
echo "HALF_ODD\n";
51+
var_dump(round(0.12345678901234565, 16, PHP_ROUND_HALF_ODD));
52+
var_dump(round(-0.12345678901234565, 16, PHP_ROUND_HALF_ODD));
53+
var_dump(round(12345678901234575, -1, PHP_ROUND_HALF_ODD));
54+
var_dump(round(-12345678901234575, -1, PHP_ROUND_HALF_ODD));
55+
var_dump(round(0.000000012345678901234525, 23, PHP_ROUND_HALF_ODD));
56+
var_dump(round(-0.000000012345678901234525, 23, PHP_ROUND_HALF_ODD));
57+
?>
58+
--EXPECT--
59+
HALF_UP, round up
60+
float(0.1234567890123457)
61+
float(-0.1234567890123457)
62+
float(12345678901234570)
63+
float(-12345678901234570)
64+
float(1.234567890123457E-8)
65+
float(-1.234567890123457E-8)
66+
67+
HALF_UP, not round up
68+
float(0.1234567890123456)
69+
float(-0.1234567890123456)
70+
float(12345678901234560)
71+
float(-12345678901234560)
72+
float(1.234567890123456E-8)
73+
float(-1.234567890123456E-8)
74+
75+
HALF_DOWN, round up
76+
float(0.1234567890123457)
77+
float(-0.1234567890123457)
78+
float(12345678901234570)
79+
float(-12345678901234570)
80+
float(1.234567890123457E-8)
81+
float(-1.234567890123457E-8)
82+
83+
HALF_DOWN, not round up
84+
float(0.1234567890123456)
85+
float(-0.1234567890123456)
86+
float(12345678901234560)
87+
float(-12345678901234560)
88+
float(1.234567890123456E-8)
89+
float(-1.234567890123456E-8)
90+
91+
HALF_EVEN
92+
float(0.1234567890123456)
93+
float(-0.1234567890123456)
94+
float(12345678901234580)
95+
float(-12345678901234580)
96+
float(1.234567890123452E-8)
97+
float(-1.234567890123452E-8)
98+
99+
HALF_ODD
100+
float(0.1234567890123457)
101+
float(-0.1234567890123457)
102+
float(12345678901234570)
103+
float(-12345678901234570)
104+
float(1.234567890123453E-8)
105+
float(-1.234567890123453E-8)

0 commit comments

Comments
 (0)