Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clearly define integer/float overflow and conversion rules #36

Merged
merged 7 commits into from
Sep 3, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 3 additions & 11 deletions spec/05-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ There is one integer type, `int`, for which the name integer is a synonym.
This type is binary, signed, and uses twos-complement representation for
negative values. The range of values that can be stored is
implementation-defined; however, the range [-2147483648, 2147483647],
must be supported.
must be supported. This range must be finite.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure - why this range must be finite? I.e. why should we ban arbitrary-precision ints?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because they don't fit well together with the rest of the language, and code right now almost certainly assumes integers are fixed-size. To implement arbitrary-precision ints, something I'm trying to do, you need to change the rest of the language, and they'd break assumptions code currently makes.


Certain operations on integer values produce a mathematical result that
cannot be represented as an integer. Examples include the following:
Expand All @@ -64,16 +64,8 @@ cannot be represented as an integer. Examples include the following:
- Applying the unary minus to the smallest value.
- Multiplying, adding, or subtracting two values.

In such cases, the resulting type and value is implementation-defined,
but must be one of the following:

- The computation is done as though the types of the values were `float`
with the result having that type.
- The result type is int and the value reflects wrap-around (for
example adding 1 to the largest value results in the smallest value).
- The computation is done as though the type had some unspecified,
arithmetic-like object type with the result being mathematically
correct.
In such cases, the computation is done as though the types of the values were
`float` with the result having that type.

The constants `PHP_INT_SIZE` (§[[6.3](06-constants.md#core-predefined-constants)](#core-predefined-constants)) and `PHP_INT_MAX` (§[[6.3](06-constants.md#core-predefined-constants)](#core-predefined-constants)) define certain
characteristics about type `int`.
Expand Down
18 changes: 16 additions & 2 deletions spec/08-conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,22 @@ result value is 0; otherwise, the result value is 1.

If the source type is `float`, for the values `INF`, `-INF`, and `NAN`, the
result value is implementation-defined. For all other values, if the
precision can be preserved, the fractional part is rounded towards zero
and the result is well defined; otherwise, the result is undefined.
precision can be preserved (that is, the float is within the range of an
integer), the fractional part is rounded towards zero. If the precision cannot
be preserved, the following conversion algorithm is used:

1. The floating point remainder (wherein the remainder has the same sign as the
dividend) of dividing the float by 2 to the power of the number of bits in
an integer (for example, 32), rounded towards zero, is taken.
2. If the remainder is less than zero, it is rounded towards
infinity and 2 to the power of the number of bits is added.
3. This result is then converted to an unsigned integer, then converted to a
signed integer by treating the unsigned integer as a two's complement
representation of the signed integer.

Implementations may implement this conversion differently (for example, on some
architectures there may be hardware support for this specific conversion mode)
so long as the result is the same.

If the source value is `NULL`, the result value is 0.

Expand Down