From: guillaume.lathoud on
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
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
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.