2a0++ misunderstanding

November 8, 2013 by Paulina Budzoń

The following eval’ed code was caused a lot of misunderstanding: https://eval.in/61309. The code looks like this:

1
2
3
4
5
6
$a = "2a0";

for($i = 0; $i < 50; $i++) {
    print "$a\n";
    $a++;
}

It outputs this:

2a0 
2a1 
2a2 
2a3 
2a4 
2a5 
2a6 
2a7 
2a8 
2a9 
2b0 
2b1 
2b2 
2b3 
2b4 
2b5 
2b6 
2b7 
2b8 
2b9 
2c0 
2c1 
2c2 
2c3 
2c4 
2c5 
2c6 
2c7 
2c8 
2c9 
2d0 
2d1 
2d2 
2d3 
2d4 
2d5 
2d6 
2d7
2d8 
2d9 
2e0 
3 
4 
5 
6 
7 
8 
9 
10 
11

Most people seeing this will thing “WHAT?!” :) Well, it’s not a bug and this behaviour is 100% correct. And documented.

Problem 1: “2a0++” = “2a1”

This result will only happen if you use the “++” operator. Using +1 won’t work like that.

Why? Because “++” acts on numbers and strings - and when dealing in strings, it acts like Perl.

When $a = "Z"; $a++; $a will become AA.

$a = "AA"; $a++; will become AB, etc.

This way, $a = "2a0"; $a++; will become "2a1".

Think: alphabet!

In contrast, $a+1 only acts on numbers - so if you try to use it on a string, it will get converted to a number. So in $a = "a20"; $a = $a+1; “2a0” will be converted to a number, which will be “2” in this case. And 2 + 1 = 3

Docs: http://php.net/manual/en/language.operators.increment.php:

PHP follows Perl’s convention when dealing with arithmetic operations on character variables and not C’s. For example, in PHP and Perl $a = ‘Z’; $a++; turns $a into ‘AA’, while in C a = ‘Z’; a++; turns a into ‘[’ (ASCII value of ‘Z’ is 90, ASCII value of ‘[’ is 91).

Problem 2: “2e0”++ = 3

The difference between 2a0 and 2e0 is exactly as it seems: the letter “e”. Following the PHP docs:

If the string does not contain any of the characters ‘.’, ’e’, or ‘E’ and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer. In all other cases it will be evaluated as a float.

Source: http://www.php.net/manual/en/language.types.string.php#language.types.string.conversion

So: "2e0" = 2 x 10⁰ = 2

And 2++ = 3

Conclusion: don’t use weird strings like “2a0” and force them to act like numbers, unless you know what you’re doing!

Posted in: Web development