From: guillaume.lathoud on 19 Jul 2010 03:40 Thanks everyone for all the answers. It seems that my first post was a bit imprecise, so just to confirm: - the system was Windows 7. - it is indeed a regression: no such issue in Safari 4. - the goal of the workaround was indeed to obtained the ES3-specified value of the RHS expression. I found the answer of Richard very interesting. In this particular case, I'll most likely end up having to apply `| 0`, otherwise I'll increasingly get exposed to annoying questions of the sort: "Why isn't my Google Map showing anything?". From a developer point of view, such a situation looks frighteningly similar to the MSIE experience. FYI, I tried to report the bug to Apple, which got me going through several barrages of - questionable - mandatory personal information requests. Maybe the bug report actually happened, maybe not. Their problem. Cheers, Guillaume On Jul 18, 5:21 pm, "Richard Cornford" <Rich...(a)litotes.demon.co.uk> wrote: > On Jul 15, 8:40 am, glathoud wrote: > > > Hello, > > > I've just had the following issue in Safari 5: > > > 0 == (0.17 * 2) >> 0 // -> true > > 0 == (0.17 * [0,1].length) >> 0 // -> false (!) > > I can confirm that in Windows Safari 5.0 (7533.16). > > > and here is a possible workaround: > > But the obvious question is what exactly is it this is supposed to be > working around? Without being sure about what it is that is being > 'worked around' there is a risk of introducing another mystical > incantation into javascript development. > > > a = (0.17 * [0,1].length) >> 0 > > 0 == a // -> true > > > (results are the same with ===) > > That comment implies that the issue is with the comparison operator. > However, > > document.write( > '((0.17 * [0,1].length) >> 0) -> '+ > ((0.17 * [0,1].length) >> 0) > ); > > - outputs:- > > ((0.17 * [0,1].length) >> 0) -> 0.3399999141693115 > > So it is not the comparison that is the issue. The expression is > evaluating to a non-integer value, which it never should because the > right shift bitwise operation should only act on 32 bit integers by > converting its operands into numbers and then 32 bit integers. > > The multiplication can be dismissed from consideration by:- > > document.write('(Math.PI >> 0) -> '+(Math.PI >> 0)); > > - outputting:- > > (Math.PI >> 0) -> 3.1415920257568373 > > So the issue is with the right shift operator, and not just with > shifting by zero as:- > > document.write('(Math.PI >> 3) -> '+(Math.PI >> 0)); > > - outputs:- > > (Math.PI >> 3) -> 3.141592025756836 > > (Note that this value is not the same as for >> 0, and that neither > value shown is Math.PI (both operations have had some impact on the > input value)) > > However, the right shift operator is apparently not totally defective > as:- > > document.write( > '(3.141592653589793 >> 0) -> '+ > (3.141592653589793 >> 0) > ); > > - outputs:- > > (3.141592653589793 >> 0) -> 3 > > -and:- > > var m = Math.PI; > document.write('(m >> 0) -> '+(m >> 0)); > > - outputs:- > > (m >> 0) -> 3 > > - which are correct. > > On the other hand:- > > function u(){return 4.5;} > document.write('(u() >> 1) -> '+(u() >> 1)); > > - outputs:- > > (u() >> 1) -> 4.500000000000002 > > (Note that 4.5 is a number that IEEE double precision floating point > numbers can represent precisely, so again this shift operation has > modified the number.) > > - while:- > > function v(){return 4;} > document.write('(v() >> 1) -> '+(v() >> 1)); > > - outputs:- > > (v() >> 1) -> 2 > > This suggests that where the left hand side operand of the shift > expression results in an integer value the shift operation will work > correctly (other tests reinforce this impression). > > However, it turns out that the right hand side operand also has an > impact:- > > document.write('(Math.PI >> -0) -> '+(Math.PI >> -0)); > > - outputs:- > > (Math.PI >> -0) -> 3 > > - which is correct. In javascript it should not be possible to > discriminate between -0 and +0, but here apparently you can. this makes > a possible work around for right shifting by zero to actually right > shift by -0, but that does not help if you wanted to shift by some other > value. > > Note that from this point on I am dropping the - document.write - from > the examples to save space. Each of the following tests had the same > form as the previous ones. > > This does, however, suggest for a feature test as:- > > ((Math.PI >> 0) == (Math.PI >> -0)) > > - should be true in ES3/5 conforming environments but not true in an > environment where (Math.PI >> 0) comes out as 3.1415920257568373. > > However, on Windows Safari 5 this came out as true. Which suggest that > in this context the (Math.PI >> 0) expression evaluated to the correct > value. Reversing the expression to:- > > (Math.PI >> -0) == (Math.PI >> 0)) > > - produced the aberrant false in Windows Safari 5, as did:- > > ((Math.PI >> 0) == (Math.PI >> 0)) > > So we are looking at a single expression that fails in one context and > succeeds in another. The implication is that it is the expression to the > right of the equality operator that is failing, but it would be a good > idea to confirm that, and to see if the equality operator itself is > involved in this particular quirk. So:- > > ((Math.PI >> 0) - (Math.PI >> 0)) -> -0.14159202575683727 > ((Math.PI >> 1) - (Math.PI >> 1)) -> -2.1415920257568364 > ((Math.PI >> 1) / (Math.PI >> 1)) -> 0.3183099497965817 > > (Correct evaluation results should be zeros for the subtractions and one > for the division). > > Asymmetrical results are found for subtraction and division operations, > and the asymmetry shows that it is the right hand side operand > expression that is failing, while the left hand operand expression is > being correctly evaluated. > > This raises the question of what happens with increasing numbers of > expressions, so:- > > (((Math.PI >> 0) - (Math.PI >> 0)) / (Math.PI >> 0)) > > Results in -0.04507015061025516, which is (((3) - (3.1415920257568373)) > / (3.1415920257568373)) and show that the left most expression evaluated > correctly but both of the following expressions failed. Then:- > > (((Math.PI >> 0) - (Math.PI >> 0)) - ((Math.PI >> 0) / (Math.PI >> 0))) > > Results in -1.096521875146582, which is ((3 - 3.1415920257568373) - (3 / > 3.1415920257568373)), so the left most expression is correct, then next > incorrect, the next correct, and the rightmost incorrect. > > A pattern may emerge if this was continued, but does not seem worth > pursuing. It is clear that these failures of shift expressions are > sensitive to the context in which the expression appears. However, > notice that:- > > (((Math.PI >> 0) - (4.5 >> 0)) / (Math.PI >> 0)) > > Resutls in -0.27323979918632646 --> (((3.1415920257568373) - (4)) / > (3.1415920257568373)), and:- > > (((Math.PI >> 0) - (u() >> 0)) / (Math.PI >> 0)) > > Results in -0.47746492469487356 --> (((3) - (4.5000000000000036)) / > (3.1415920257568373)) > > (where - u - is the function that returns 4.5 defined above) - shows the > leftmost (Math.PI >> 0) expression fail in one case and succeed in > another. > > Tests on other bitwise operators show precisely the same issue for > unsigned right shift ( >>> ), but no issues with bitwise OR ( | ). > > If you wanted a workaround for this particular Safari 5 bug then I would > suggest replacing all occurrences of - >> 0 - (right shift zero bits) > with - | 0 - (bitwise OR with zero), as that would have the same > truncating side effect for a negligible loss of performance in other > browsers, and when shifting by other numbers of bits, because the shift > expression seems to always be successful when applied to integer values, > it should be practical to apply - | 0 - to the left hand side operand > prior to the application of the shift operation. That is (Math.PI >> 1) > becomes ((Math.PI | 0) >> 1). The effect would be less disruptive (less > obfuscating) than introducing new local variables to hold the results of > pre-evaluated expressions. > > On the other hand, I would recommend doing nothing at all and letting > Safari 5 suffer for its faults. For one thing, if a web browser wants to > advertise itself as being the fastest browser ever it would be > hypocritical for it (though its bugs) to force developers to use > workarounds that harm the performance of all of its competitors. The > second reason is that if Safari 5 has been allowed out of the door with > this ridiculous context-sensitive f**k up of a simple low-level > operation in place the odds are really good that there are more. These > days it does not seem sensible to start making new concessions for new > web browsers that cannot even conform to the basics of the ten year old > ES 3 standard. > > Richard.
From: Dr J R Stockton on 19 Jul 2010 15:44 In comp.lang.javascript message <625546tc67ui4q61vranb7daplnfr70742(a)4ax. com>, Sun, 18 Jul 2010 06:44:23, Swifty <steve.j.swift(a)gmail.com> posted: >On Sat, 17 Jul 2010 19:58:52 +0100, Dr J R Stockton ><reply1028(a)merlyn.demon.co.uk> wrote: > >>as far as I know, my Safari 4.0.5 is the latest Windows >>version. > >I have 5.0 and it must have come via the standard Apple software >automatic updating process, as I did nothing explicit to obtain it. What process? I've not seen it. <http://support.apple.com/kb/DL1046> does offer 5.0 for XP, though. I don't want automatic updates, but I do want automatic notification. Aside Should <H3 name="Op">Operation</H3> work reliably? -- (c) John Stockton, nr London, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 7. Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links. Command-prompt MiniTrue is useful for viewing/searching/altering files. Free, DOS/Win/UNIX now 2.0.6; see <URL:http://www.merlyn.demon.co.uk/pc-links.htm>.
From: Ry Nohryb on 20 Jul 2010 04:27
On Jul 19, 9:40 am, "guillaume.lathoud" <guillaume.lath...(a)alpstein.de> wrote: > > FYI, I tried to report the bug to Apple, which got me going through > several barrages of - questionable - mandatory personal information > requests. Maybe the bug report actually happened, maybe not. Their > problem. You could download the latest webkit from http://nightly.webkit.org/ to see if this bug isn't fixed already. If it isn't, you could then go to http://webkit.org/quality/reporting.html to report it. -- Jorge. |