Repository navigation
Compute the numeric operators on NumberSet - #6955
Merged
Merged
Conversation
The operator helpers read integer and float intervals from the members of a type through a chain of instanceof checks. A NumberSet now carries the integer intervals, the float intervals and NAN of a type, so they read those instead. Amp-Thread-ID: https://ampcode.com/threads/T-01a1a1e7-5e72-7235-a4b2-ba1b689f7e1b
+, -, *, /, << and >> now run as NumberSet methods on the operands' toNumberSet(), pair by pair: integer pairs keep the integer rules, every other pair uses the float interval corners. This replaces the interval and float-range special cases in OperatorTypeHelper, and float members of integer unions are no longer passed through. Amp-Thread-ID: https://ampcode.com/threads/T-01a1a1e7-5e72-7235-a4b2-ba1b689f7e1b
The == narrowing follows the analysed PHP version: PHP 7 compares a non-numeric string with a number as a number, has no Stringable, and BcMath\Number compares as its number since PHP 8.4. The nsrt comparisons now run inside PHP_VERSION_ID guards, so their results no longer depend on the PHP version running the tests. Amp-Thread-ID: https://ampcode.com/threads/T-01a1a1e7-5e72-7235-a4b2-ba1b689f7e1b
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
Type::toNumberSet(): ?NumberSet, which describes the numbers a type holds as integer intervals, float intervals and a NAN flag. The trait default returnsnull; it is implemented onIntegerType,ConstantIntegerType,IntegerRangeType,FloatType,ConstantFloatType,FloatRangeTypeandUnionType.The arithmetic operators
+,-,*,/,<<and>>now run asNumberSetmethods, such asNumberSet::add(NumberSet $right, PhpVersion $phpVersion), instead of theinstanceofchains inOperatorTypeHelper. Each pair of members is computed on its own: two integer intervals use the integer rules, and every other pair uses the float interval corners.Ranges are kept as intervals and are never expanded value by value. Above
CALCULATE_SCALARS_LIMIT, a set collapses to its hull.Two commits:
Type::toNumberSet(). The interval readers inOperatorTypeHelperandExponentiateHelpernow read the set.NumberSet. This removesintegerRangeMath,floatRangeMath,floatIntervalMathand the related helpers. Float members of integer unions are now computed instead of passed through:int<1, 5> + (1.5|2)isfloat<2.5, 6.5>|int<3, 7>.Changed expectations, each narrower and still sound:
int<5, max> / -2isint<min, -3>(wasint<min, -2>, which was wrong: 6 / -2 = -3 is the first exact integer result)1 / $intis-1|1|float$float * 0is0.0|NAN, and0 * $intOrFloatis0|0.0|NANrand() * 0.1isfloat<0.0, max>for ($xi = $x0; $xi < $xn; $xi += 0.1),$xnisint<2, max>Both commits include the Turbo C++ mirrors (
NumberSet.cpp,OperatorTypeHelper.cpp). The test suite passes with and without the extension. A local operator fuzzer that compares the inferred types with runtime results on PHP 7.4 to 8.6 passes, and self-analysis output is identical with Turbo on and off on PHP 8.4 and 8.5.