develooper Front page | perl.perl5.porters | Postings from November 2000

Re: pp_add -> pp_i_add efficiency hack?

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
November 14, 2000 08:24
Subject:
Re: pp_add -> pp_i_add efficiency hack?
Message ID:
20001114162429.D87735@plum.flirble.org
On Tue, Nov 14, 2000 at 02:10:31PM +0000, Nicholas Clark wrote:
> On Tue, Nov 14, 2000 at 07:57:58AM -0600, Jarkko Hietaniemi wrote:
> > ./perl -Ilib -MDevel::Peek -wle '$in = "18446744073709551616"; print $in; $zero = 0; $in+=$zero;{use integer; $in + $zero;} Dump ($in)'
> > Useless use of integer addition (+) in void context at -e line 1.
> > 18446744073709551616
> > SV = PVNV(0x14003f0d8) at 0x140014608
> >   REFCNT = 1
> >   FLAGS = (IOK,NOK,pIOK,pNOK,IsUV)
> >   UV = 18446744073709551615
> >   NV = 1.84467440737096e+19
> >   PV = 0x140036308 "18446744073709551616"\0
> >   CUR = 20
> >   LEN = 21
> > 
> > Egads.  I have the same affliction.  Because 18446744073709551616
> > doesn't fit in 64-bit UVs and 4294967296 in 32-bit UVs, the IOK/isUV
> > flags definitely shouldn't be turned on.
 
> It's the same as
> 
> perl -MDevel::Peek -wle '$in = "3.1"; print $in; $zero = 0; $in+=$zero; {use integer; $in + $zero;} print $in; Dump ($in)'
> Useless use of integer addition (+) in void context at -e line 1.
> 3.1
> 3.1
> SV = PVNV(0x81036d8) at 0x810abb8
>   REFCNT = 1
>   FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK)
>   IV = 3
>   NV = 3.1
>   PV = 0x8109ab0 "3.1"\0
>   CUR = 3
>   LEN = 35
> 
> 
> the IV slot holds the accurate integer representation of the NV, but
> the IV has lost precision.
> 
> is the cast (IV) expensive?
> If it is, then it would make sense to flag in some way that IV slot is valid,
>   but NV preferred (so that polymorphic operators know what to do)
>   [not the current flags which are saying that the two are equivalent and
>    equally valid]
> If not, then I see no point storing anything.

OK. What does a scalar with IV and NV both OK mean?
And what are the private flags actually used form?
[ie when are things SvNOKp set but not SvNOK ?]

sv_2iv says:

	/* We want to avoid a possible problem when we cache an IV which
	   may be later translated to an NV, and the resulting NV is not
	   the translation of the initial data.
	
	   This means that if we cache such an IV, we need to cache the
	   NV as well.  Moreover, we trade speed for space, and do not
	   cache the NV if not needed.
	 */
	if (numtype & IS_NUMBER_NOT_IV) {
	    /* May be not an integer.  Need to cache NV if we cache IV
	     * - otherwise future conversion to NV will be wrong.  */
	    NV d;



There seems to be an implicit assumption that NV preserves IV always,
and that all operations take place on NV, not IV, so if NV is present
it always takes precedence.

And sv_2iv only stores the NV if converting the PV and the PV contains
something that doesn't fit in an IV
(ie it doesn't clear the NvOK flag if converting an integer NV to IV)

So it doesn't matter if NV=3.1 and IV=3 because 3.1 always used to be
seen everywhere that didn't force integers. NV was canonical.


Am I right in taking this as historical precedent?

But now we're effectively trying to make maths polymorphic, so that
IV and NV carry equal weight, and either could be the canonical value.

Am I right in thinking this is going to mean changing the 2nv and 2iv and 2uv
code in sv.c?

And should it be that SvIOKp is true when the IV holds the accurate value,
but SvIOK is only true when the IV is precise;
SvNOKp when the NV holds an accurate value, but SvNOK only true when that
value is precise?

by which I mean 3.1 would be
IV = 3
NV = 3.1
FLAGS = (NOK,pIOK,pNOK)

and  18446744073709551615 would be
FLAGS = (IOK,pIOK,pNOK,IsUV)
UV = 18446744073709551615
NV = 1.84467440737096e+19

to indicate that the IV is correct, the NV an approximation?

Or is this wrong because I am missing something?

Nicholas Clark

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About