Skip to content

Commit 44a9c53

Browse files
Add is_representable_as_float() and is_representable_as_int
1 parent 16b2fc4 commit 44a9c53

File tree

6 files changed

+782
-1
lines changed

6 files changed

+782
-1
lines changed

ext/standard/basic_functions.stub.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3700,6 +3700,16 @@ function is_iterable(mixed $value): bool {}
37003700
*/
37013701
function is_countable(mixed $value): bool {}
37023702

3703+
/**
3704+
* @compile-time-eval
3705+
*/
3706+
function is_representable_as_float(mixed $value): bool {}
3707+
3708+
/**
3709+
* @compile-time-eval
3710+
*/
3711+
function is_representable_as_int(mixed $value): bool {}
3712+
37033713
/* uniqid.c */
37043714

37053715
#ifdef HAVE_GETTIMEOFDAY

ext/standard/basic_functions_arginfo.h

Lines changed: 9 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
--TEST--
2+
Test is_representable_as_float() function
3+
--SKIPIF--
4+
<?php if (PHP_INT_SIZE != 8) die("skip this test is for 64-bit systems only"); ?>
5+
--FILE--
6+
<?php
7+
$representable_as_float = array(
8+
0,
9+
1,
10+
-1,
11+
42,
12+
-42,
13+
14+
9007199254740992, // 2^53
15+
-9007199254740992, // -2^53
16+
9007199254740991, // 2^53 - 1
17+
-9007199254740991, // -(2^53 - 1)
18+
19+
// from 2^53 to 2^54, only even numbers are exactly representable
20+
9007199254740994, // 2^53 + 2
21+
9007199254740996, // 2^53 + 4
22+
18014398509481984, // 2^54
23+
-9007199254740994, // -(2^53 + 2)
24+
25+
// from 2^54 to 2^55, only multiples of 4 are exactly representable
26+
18014398509481988, // 2^54 + 4
27+
18014398509481992, // 2^54 + 8
28+
36028797018963968, // 2^55
29+
30+
// from 2^55 to 2^56, only multiples of 8 are exactly representable
31+
36028797018963976, // 2^55 + 8
32+
36028797018963984, // 2^55 + 16
33+
72057594037927936, // 2^56
34+
35+
// pure powers of two
36+
1152921504606846976, // 2^60
37+
2305843009213693952, // 2^61
38+
39+
0.0,
40+
-0.0,
41+
1.0,
42+
-1.0,
43+
3.14,
44+
-3.14,
45+
46+
INF,
47+
-INF,
48+
NAN,
49+
50+
2,
51+
4,
52+
8,
53+
16,
54+
1024,
55+
56+
"0",
57+
"1",
58+
"-1",
59+
"42",
60+
"0.0",
61+
"1.0",
62+
"-1.0",
63+
"3.14",
64+
"-3.14",
65+
"1e10",
66+
"-1e10",
67+
"1.5e-10",
68+
"9007199254740992", // 2^53
69+
"-9007199254740992", // -2^53
70+
71+
72+
"9007199254740994", // 2^53 + 2
73+
"18014398509481988", // 2^54 + 4
74+
"36028797018963976", // 2^55 + 8
75+
76+
" 42 ",
77+
"\t1.5\n",
78+
"\r-3.14\v",
79+
);
80+
81+
foreach ($representable_as_float as $value) {
82+
var_dump(is_representable_as_float($value));
83+
}
84+
85+
$not_representable_as_float = array(
86+
9007199254740993, // 2^53 + 1
87+
-9007199254740993, // -(2^53 + 1)
88+
9007199254740995, // 2^53 + 3
89+
90+
// odd numbers in 2^53 to 2^54 range
91+
9007199254740995, // 2^53 + 3
92+
9007199254740997, // 2^53 + 5
93+
18014398509481985, // 2^54 + 1
94+
95+
// not multiples of 4 in 2^54 to 2^55 range
96+
18014398509481986, // 2^54 + 2
97+
18014398509481990, // 2^54 + 6
98+
36028797018963970, // 2^55 + 2
99+
100+
// not multiples of 8 in 2^55 to 2^56 range
101+
36028797018963972, // 2^55 + 4
102+
36028797018963978, // 2^55 + 10
103+
72057594037927940, // 2^56 + 4
104+
null,
105+
true,
106+
false,
107+
"",
108+
"hello",
109+
"123.456.789",
110+
"1e400",
111+
"-1e400",
112+
113+
[],
114+
[1, 2, 3],
115+
new stdClass(),
116+
117+
118+
"9007199254740993", // 2^53 + 1
119+
"18014398509481986", // 2^54 + 2 (not multiple of 4)
120+
"36028797018963972", // 2^55 + 4 (not multiple of 8)
121+
122+
"0x42",
123+
"0xFF",
124+
125+
"0b1010",
126+
);
127+
128+
$fp = fopen(__FILE__, "r");
129+
$not_representable_as_float[] = $fp;
130+
131+
foreach ($not_representable_as_float as $value) {
132+
var_dump(is_representable_as_float($value));
133+
}
134+
135+
class TestClass {
136+
public function __toString() {
137+
return "42";
138+
}
139+
}
140+
141+
$obj = new TestClass();
142+
var_dump(is_representable_as_float($obj));
143+
144+
class TestClass2 {
145+
public function __toString() {
146+
return "not_numeric";
147+
}
148+
}
149+
150+
$obj2 = new TestClass2();
151+
var_dump(is_representable_as_float($obj2));
152+
153+
fclose($fp);
154+
?>
155+
--EXPECT--
156+
bool(true)
157+
bool(true)
158+
bool(true)
159+
bool(true)
160+
bool(true)
161+
bool(true)
162+
bool(true)
163+
bool(true)
164+
bool(true)
165+
bool(true)
166+
bool(true)
167+
bool(true)
168+
bool(true)
169+
bool(true)
170+
bool(true)
171+
bool(true)
172+
bool(true)
173+
bool(true)
174+
bool(true)
175+
bool(true)
176+
bool(true)
177+
bool(true)
178+
bool(true)
179+
bool(true)
180+
bool(true)
181+
bool(true)
182+
bool(true)
183+
bool(true)
184+
bool(true)
185+
bool(true)
186+
bool(true)
187+
bool(true)
188+
bool(true)
189+
bool(true)
190+
bool(true)
191+
bool(true)
192+
bool(true)
193+
bool(true)
194+
bool(true)
195+
bool(true)
196+
bool(true)
197+
bool(true)
198+
bool(true)
199+
bool(true)
200+
bool(true)
201+
bool(true)
202+
bool(true)
203+
bool(true)
204+
bool(true)
205+
bool(true)
206+
bool(true)
207+
bool(true)
208+
bool(true)
209+
bool(true)
210+
bool(true)
211+
bool(false)
212+
bool(false)
213+
bool(false)
214+
bool(false)
215+
bool(false)
216+
bool(false)
217+
bool(false)
218+
bool(false)
219+
bool(false)
220+
bool(false)
221+
bool(false)
222+
bool(false)
223+
bool(false)
224+
bool(false)
225+
bool(false)
226+
bool(false)
227+
bool(false)
228+
bool(false)
229+
bool(false)
230+
bool(false)
231+
bool(false)
232+
bool(false)
233+
bool(false)
234+
bool(false)
235+
bool(false)
236+
bool(false)
237+
bool(false)
238+
bool(false)
239+
bool(false)
240+
bool(false)
241+
bool(true)
242+
bool(false)

0 commit comments

Comments
 (0)