Why does 1...1 evaluate to 10.1?

Gino Pane picture Gino Pane · Jul 17, 2017 · Viewed 10.2k times · Source

I've just faced a little PHP snippet from 3v4l: https://3v4l.org/jmrZB

echo 1...1; //10.1

And I'm afraid I have no idea how to explain its results. Why is this considered valid at all?

Answer

axiac picture axiac · Jul 17, 2017

The dot (.) has two roles in PHP:

  1. As decimal digit, when it is part of a real number, e.g. 1.1. Both the integral part and the decimal part are optional on real numbers but not on the same time. This means both 1. and .1 are valid real numbers in PHP but . is not a number.
  2. As the string concatenation operator. This operator connects two string sub-expressions into a larger expression. The value of the larger expression is the concatenation of the string values of the sub-expressions. The sub-expressions that are not strings are converted to strings before concatenation.
    E.g. 1 . 1 is the same as '1' . '1' and its value is the string '11'.

The expression 1...1 is parsed as 1. . .1. According to those said above, 1. and .1 are real numbers (1.0 and 0.1) and the middle dot (.) is the string concatenation operator.

When converts numbers to strings, PHP uses the minimum amount of characters required for this operation. If a real number has only integral part then it represents the number as integer, without decimal point and decimals.

This is why 1. . .1 is the same as '1' . '0.1' and the final value of the expression is 10.1.

Why is 1...1 parsed this way?

The parser reads the expression from left to right. 1 tells it a number starts there. 1. is a valid real number but 1.. is not. It keeps 1. as a number then the next dot is the concatenation operator. The next ., being followed by a digit, is the beginning of another real number (.1).

All in all, 1...1 is the same as 1. . .1.