Posted Apr 22, 2012 10:02 UTC (Sun) by ajf (subscriber, #10844)
[Link]
I don't have a compiler at hand here, but auto-boxing introduced in Java 5 is usually the culprit behind "surprising" Java behaviour. I sometimes have Eclipse configured to mark up implicit conversion between primitive and boxed object (but to be honest it's usually not worth it; I've never encountered any such surprises anywhere other than intentional puzzles like yours).
One possible answer, then, would be that T1 and T3 are Integer, while T2 is int; v1 and v3 are both new Integer(1000), and v2 is 1000. The a == b and b == c expressions will un-box a and c respectively, but a == c will compare object references (and find them different since both were constructed with new).
Another fun quirk only ever encountered in puzzles like this: if you change v1 and v3 to, say, 7, (ie, a primitive value that will be boxed in order to be assigned to a and c), you'll get "false" instead, because a != c will be false, since Integer.valueOf(int) (which is the method called to convert the primitive values to Integer objects to be assigned to a and c) happens to maintain a pool of Integer objects for small values, and will return the same value for both a and c.
Getting back to the topic at hand, the difference to note here is that these are carefully-crafted puzzles in Java; the problem with PHP is that quirks like this are something you more or less always have to think about when you're writing PHP.
PHP: a fractal of bad design (fuzzy notepad)
Posted Apr 22, 2012 12:25 UTC (Sun) by IkeTo (subscriber, #2122)
[Link]
You're right. The following program exhibit the said behavior:
public class T {
public static void main(String[] args) {
Integer a = 1000;
int b = 1000;
Integer c = 1000;
System.out.println(a == b && b == c && a != c);
}
}
Amazingly, there is another ways to cause the said behavior using only primitive types. (See IPSC 2008 Problem C).
And yes, I just try to be humorous when I said "even Java equality is not transitive". PHP is so horribly broken that I won't even touch it with a ten feet pole.
On the other hand, if even the very well specified Java language has non-transitive equality, you can expect that most other languages have similar behavior. One thus cannot just say a language is bad because of it. Instead, one would instead say something like "PHP equality has very surprising behavior that makes it very undesirable for programmers".
PHP: a fractal of bad design (fuzzy notepad)
Posted Apr 22, 2012 18:24 UTC (Sun) by Cyberax (✭ supporter ✭, #52523)
[Link]
Well, use of equality for object types in Java is dangerous. Which is told in every textbook on it.
On the other hand, the real equality comparison operation ('equals' method) is transitive and commutative. Well, unless you screw it up intentionally.
PHP: a fractal of bad design (fuzzy notepad)
Posted Apr 26, 2012 0:10 UTC (Thu) by IkeTo (subscriber, #2122)
[Link]
It depends on what you call "screw it up intentionally". The following program output "true" for most numbers larger than 16777216 or smaller than -16777217. It is 127/128 of the range [-2^31, 2^31-1] of int:
public class T {
public static void main(String[] args) {
int a = Integer.parseInt(args[0]);
float b = a;
int c = a + 1;
System.out.println(a == b && b == c && a != c);
}
}
Similar behavior can be found if you replace int by long and float by double.
PHP: a fractal of bad design (fuzzy notepad)
Posted Apr 26, 2012 1:50 UTC (Thu) by Cyberax (✭ supporter ✭, #52523)
[Link]
That's completely expected and correct behavior of equality comparisons involving floating point numbers. It's also noted in every textbook under the DO NOT USE category.