develooper Front page | perl.perl5.porters | Postings from February 2003

Re: [perl #20827] Unexpected scientific notation.

Thread Previous | Thread Next
Nicholas Clark
February 15, 2003 14:21
Re: [perl #20827] Unexpected scientific notation.
Message ID:
On Wed, Feb 12, 2003 at 03:12:43AM +0000, wrote:
> Nicholas Clark <> wrote:
> :>     $ perl -wle 'print 1597009560 ** 2'
> :>     2550439534731393600
> :
> :exponentiation will be done as NVs
> :It will be constant folded in the peephole optimiser in op.c:
> :
> :            /* Only bother to attempt to fold to IV if
> :               most operators will benefit  */
> :            SvIV_please(sv);
> :#endif
> Hmm, should this not special case integer power of an integer, and other
> calculations that we can guarantee should give an integer? And leave it
> to the special-casing to handle the conversion rather than this separate
> blanket check? It seems quite correct for 1.4142...(30) ** 2 to give 2.000,
> and I think I'd be happy for sin(0) to return 0.000.

Errr. That sounds like hard work. Part of me thinks that we should remove
that "optimisation" altogether - the first time an operator such as pp_add
needs the value as an integer, it will do the conversion.

> :If anything, the peephole optimiser should be changed, and the constant
> :1597009560 ** 2 left as an NV. This would make the first two the same, and
> :the second two both scientific notation.
> I agree they should be the same. I think the answer though is to move the
> optimisation (hmm, correction) to where it belongs.

Ah. We think the same way. I think we achieve this by deleting the above
code entirely. Of course, I've not tested this :-)

> The simplistic patch below breaks no tests here. Is this the direction
> we should be going?

Not sure. If there are no bugs in the implementation, then I think raising
integers to the power of integers that don't overflow integers with integer
arithmetic shouldn't be detectable at perl level.

> Since I was looking at the code anyway, it occurred that it seems a shame
> not to use direct multiplication for small numbers other than pow(2^m, n).
> I'd have thought that integer powers with overlarge results other than
> powers of two would be quite rare, so I think this should also be a win
> for any cases we can quickly enough detect would fit in a UV; the second
> patch below (over the first, but independent) is an attempt at implementing
> that using a simple bitsize test, which also breaks no tests here. Comments
> likewise welcomed.

At the time that the power of two hack was put in (to make Irix long double
2**31 happy) there were comments on p5p that I'd not got the implementation
optimally efficient. (I think that it went round a loop once too many).
I didn't think that Jarkko applied the optimisation patch (I forget who it
was from) because we were too close to 5.8.0 release.
Did that patch ever get in?

> Do we have a macro for 'index of the highest bit set in a UV'? ISTR there
> are processors with an opcode for this ...

Not that I know of.

> Also, when we know C<bit> is set, wouldn't C< power -= bit > be faster
> mostwheres than C< power &= ~bit >?

I think so. Certainly the former will be 1 opcode on ARM, whereas the latter
may have to be 2 (unless the optimiser is really really clever and can do
the conversion). So I'll say "yes", 'cos I like ARM to go faster. :-)

> And fifthly, should be returning (IV)1 when power is (IV)0, regardless
> of the type (assuming non-zero) of the base?

Yes, presumably unless the base isn't 0, -0, Inf, -Inf, NaN
(or whichever D'oh! platform had -NaN)

From memory Irix long doubles was quite bitchy when it came to testing
numeric stuff.
(Although something DEC, Crays, and NEC SX series machines were also trouble)

Nicholas Clark

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About