9 ms·
This behavior is documented here: http://php.net/manual/en/language.operators.comparison.php http://php.net/manual/en/language.operators.comparison.php If yo
by hiddenbayes 14y ago
This behavior is documented here: http://php.net/manual/en/language.operators.comparison.php http://php.net/manual/en/language.operators.comparison.php
If you compare a number with a string or the comparison
involves numerical strings, then each string is converted
to a number and the comparison performed numerically.
- muyuu 14y agoIMO this conversion should fail if the number represented is not valid, or fall back to arbitrary precision math (GMP library for instance), instead of silently making such a questionable conversion. I generally avoid exceptions/error_levels in all languages but this is probably a good cause for them, in order to keep the rest backwards compatible.
- fffggg 14y agoHow do you test that it isn't valid? I think you may be underestimating the difficulty in predicting whether a particular decimal number can be accurately represented as a floating point type. It may be non-obvious, but the representation of precise numbers changes depending on the number base. For example, in base 10, we can't precisely represent 1/3. In base 3, we can (0.1). In base 2, we can't precisely represent 0.1, or 1/10. A simple number such as 0.1 has no precise representation in base 2. In this case in php, the truncation happens due to loss of precision in the mantissa of the double precision float. But there are so many other ways to lose precision, I don't think it's reasonable to ask a language to attempt to account for them. This is why languages should have clear rules about when type conversion occurs, and allow the user to prevent it when it isn't desirable. edit: in fact, amusingly, php seems to be doing some non-standard stuff with its floats. I was going to make a point about how you can't determine if a double is a "correct" representation of a string decimal, but in mocking an example I discovered something odd. Check this out: This is what one should expect: $ ruby -e'puts "%5.25f" % 0.1' 0.1000000000000000055511151 $ perl -wle'printf "%5.25f\n", 0.1' 0.1000000000000000055511151 But in php: $ php -r'printf("%5.25f\n", 0.1);' 0.1000000000000000000000000 $ php -r'printf("%5.25f\n", "0.1");' 0.1000000000000000000000000 Is php changing the type conversion? Or not using double precision at all?
- muyuu 14y agoPrecision in floats is accepted as a fact of life. Converting exceedingly big INT string literals to bigger float types is a hack to win some naive benchmarks against languages doing native proper arbitrary precision. This shouldn't have happened in the first place, but since it's there and backwards compatibility is important, it could be shown in a warning error_level[1] that the conversion happened, so the user could at least check that and hack a solution together. [1] This doesn't really happen in PHP, but you have $php_errormsg that can be set without stopping execution (as happens with some errors/warnings when error_level is not set to E_STRICT, and below that depending on the error). This errors could be triggered in a new level, let's say "E_PEDANTIC".
- fffggg 14y agoYou just reiterated my point. This is precisely why your original suggestion of failing an "invalid" conversion is untenable. ALL conversions lack precision -- there is no such thing as an "invalid" conversion.
- muyuu 14y agoNope, there are conventions. We have two distinct problems here: - strings converting to numbers without there being any number on any side. "Peculiar" of PHP but easy to circumvent using string comparison. IMO belongs in PHP4 but not at all in PHP5, which is an attempt at a "general-purpose" language. To be frank, I thought PHP4 made more sense because it was 1st of class at what it did, while PHP5 falls short to a number of languages in basically everything. - automatic integer-to-float comparison to accomodate bigger integers. A horrible hack to squeeze a little extra performance in naive benchmarks in computers with no native 64 bit integer support. This really makes no sense whatsoever now and may have had some partial justification in the early 90s, prior to PHP4 even. Both ideas are terrible and pretty much unique to PHP of all popular languages. This is not a philosophical debate about typing styles or the existence of perfect type conversions. PHP's problems in this regard are relics from a dubious past.
- 14y ago
- wladimir 14y agoWho ever thought of this? I can understand "don't use == for strings", or implicit conversion when one of the arguments is a number, but this is extremely sneaky as it will only behave this way with two numerically-looking strings. Ouch. Why does it even do that check, wasting cycles beyond a normal string comparison? It looks like an elaborate and cruel trap for novice programmers. Edit: I know == is not a string comparison. But you'd expect it to fail in a predictable way when passed strings that are not parseable as numbers, instead of trying to fall back on a string comparison so that people get the wrong idea.
- dchest 14y agoNot defending the bad design decision, but string comparison in PHP is strcmp, not ==.
- pornel 14y agoPHP gets input from various places, and one might want "1.00" from a form or URL to equal "1.0" read from a cookie or via database adapter that stringifies everything.
- kingkilr 14y agoIf only we had some sort of way of explicitly telling our computers that we wanted to to convert a sequence of characters into a number.
- ctdonath 14y agoAh, an obscure point of absurdity which utterly kills my pending interest in the language. If this sort of thing exists under the hood, revealed only by a detailed analysis of the specification, what other nonsense is there? Going so far as analyzing a string to determine whether it consists entirely of numbers for the non-sequitur process of then and only then converting it to what it isn't for logical evaluation is working pretty hard to do something counter-intuitive; might be tolerable if it actually preserved all digits, but not only does it work hard to convert a string to an integer, it then converts large integers in to floating-point values - not just one, but two layers of explicitly undesired and unnecessary and unreasonable typecasting. I'm currently working with barcodes: numerical strings from 6 to 55 digits. In no way can I risk having one barcode be evaluated as equal to a literally different barcode just because the symbols in that string just happen to exhibit a passing resemblance to data of a different type. Again, it's not just that it has loose typing. It's that it's taking what is OBVIOUSLY a string, converting it to an integer, THEN converting it to yet another data type which imposes data loss. Intolerable for real-world use. A toy language. Alas, PHP, we hardly knew you... ETA: Oh, I'd love to know the justification for the downvoting.
- hackermom 14y ago"Intolerable for real-world use. A toy language. Alas, PHP, we hardly knew you..." Have you been out on the internet the past decade? Do you have a tendency to make extremities of things and trying to stand the needle on its tip?
- ctdonath 14y agoIt throws away data on an obtuse, obscurely-documented, whim. Making extremes? My medical application would fail FDA approval in minutes if ported to PHP precisely because of this issue.
- luser001 14y agoAll languages have their idiosyncrasies. You can pick out some obscure aspect of any language and say $LANG sucks. Btw, PHP's behavior doesn't totally make sense to me either. But I'm willing to assume that its users and designers have thought this through and it makes sense for PHP's intended use cases, because I don't know PHP. Javascript (which most people on HN seem to like) also has similar issues (null vs. undefined, == and === etc). It got so bad that "Javascript: the good parts" had to be written to define a de-facto sane subset of the language. People are actually writing in Coffeescript (in part) to avoid Javascript's pitfalls. YMMV.
- danso 14y agoWhat's the low-level cost to determine whether a given string is "numerical" or not? Also, would "001" be considered a numerical string? This reminds me of Excel-like programs that by default, automatically detect (and convert) fields that appear to be dates/strings...often to catastrophic effect.
- drunkpotato 14y agoYou just hit upon by far my least favorite bug in Excel. Any integers around I think 40000, which are quite easy to come upon in various datasets, are automatically "detected" as a date. It makes Excel very dangerous for reading CSV files.