develooper Front page | perl.perl5.porters | Postings from August 2010

Re: [perl #76756] PATCH: srand returns the seed

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
August 2, 2010 06:34
Subject:
Re: [perl #76756] PATCH: srand returns the seed
Message ID:
20100802133407.GT48531@plum.flirble.org
On Wed, Jul 28, 2010 at 10:11:13AM -0700, Jan Dubois wrote:
> On Wed, 28 Jul 2010, Jan Dubois wrote:
> > On Wed, 28 Jul 2010, Nicholas Clark wrote:
> > > And if you're really up for it, there's a bug with no obvious fix if your
> > > system supports negative zero:
> > >
> > > $ perl -wle '$a = 0/-1; print $a ? "T" : "F"; print $a; print $a ? "T" : "F";'
> > > F
> > > -0
> > > T
> > >
> > >
> > > the problem being that the implementation of true/false is
> > >
> > > is there a string value?
> > >   Y: is it "0" or ""?
> > > is there a numeric value?
> > >   Y: is it == 0
> > > ...
> > >
> > >
> > > IEEE floating point has -0 numerically equal to 0, so that makes it false.
> > > But if you then cause that value to be used as a string (such as that print)
> > > then the string representation is cached, and it doesn't meet the value of
> > > falsehood.
> > >
> > > This *is* inconsistent with the documentation, and with the general intended
> > > behaviour, but I can't see a way to fix it. Whereas the behaviour of strings
> > > such as "0e0" and "00" and "0.0" is consistent with both the intent and the
> > > documentation.
> > 
> > Well, you _could_ add a special case to the string comparison:
> > 
> > is there a string value which is "-0" and a numeric value?
> >   Y: is the numeric value == 0
> > is there a string value?
> >   Y: is it "0" or ""?
> > is there a numeric value?
> >   Y: is it == 0
> > ...
> > 
> > This would preserve the boolean value of -0 across stringification, at a minimal
> > runtime costs for all boolean value checks.
> > 
> > I have no opinion right now if we _should_ do this though.
> 
> That rule will fail in the opposite direction:
> 
> $ perl -e '$a = "-0"; print $a ? "T" : "F"; $_=$a+1.23; print $a ? "T" : "F";'
> 
> It prints "TT" now but would print "TF" under the new rule.
> 
> There is no way to distinguish if the SV started out as an NV and added
> the PV later, or if it was the other way round.  So I don't see a way to
> fix it either, after all.

I can see one potential crafty way to avoid the above inconsistency, which
is to change sv_2pv_flags() so that it doesnt (completely) cache the string
conversion for -0.

ie currently, we have

$ perl -MDevel::Peek -wle '$a = 0/-1; Dump($a); print "\n$a\n"; Dump($a)'
SV = NV(0x10081a1e0) at 0x100800fe0
  REFCNT = 1
  FLAGS = (NOK,pNOK)
  NV = -0

-0

SV = PVNV(0x100804730) at 0x100800fe0
  REFCNT = 1
  FLAGS = (NOK,POK,pNOK,pPOK)
  IV = 0
  NV = -0
  PV = 0x100201a80 "-0"\0
  CUR = 2
  LEN = 40



If that last one changed to:

SV = PVNV(0x100804730) at 0x100800fe0
  REFCNT = 1
  FLAGS = (NOK,pNOK,pPOK)
  IV = 0
  NV = -0
  PV = 0x100201a80 "-0"\0
  CUR = 2
  LEN = 40


(note, no POK there) then the existing logic of:

is there a string value?
  Y: is it "0" or ""?
is there a numeric value?
  Y: is it == 0
...


would work - the hack of not setting SvPOK() for this case would mean that
"is there a string value?" would not be true, so the fallthrough to the next
clause would happen, where there *is* a numeric value, and as -0 == 0, it
would be false.


What I can't work out is whether there is any shortcut way in ANSI C to find
out whether a value is -0, distinct from 0, short of *printf().

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