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