Re: Determining whether a value is zero.
by BrowserUk (Patriarch) on Mar 10, 2011 at 13:28 UTC
|
I don't suppose that you would entertain any argument with your arbitrary definition of what constitutes zero?
Any definition that deems "0" as zero, but "00", "0.0" & "0 " as not, is so arbitrary as to render the challenge pointless.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] |
|
| [reply] |
|
I'm not adverse to a purely intellectual challenge.
But the specification of what is and what is not zero doesn't seem to comply with any either real-world or rational definition that I can think of. I cannot think of any existing implementation that would interprete "0" as zero, and not "00" or "0 ". Nor can I see any rational for doing so.
Without some logic as to why these arbitrary rules have been picked, you might as well do:
#! perl -slw
use strict;
use feature qw[ state ];
use Scalar::Util qw[ dualvar ];
my @true = ( 0, "0", 0.0, Scalar::Util::dualvar( 0, 1 ) );
my @false = (
1, "foo", "00", "0 ", undef, "",
Scalar::Util::dualvar( 1, 0 ), "0.0"
);
sub isZero {
state %isZero;
unless( %isZero ) {
$isZero{ $_ } = 1 for @true;
$isZero{ $_ } = 0 for @false;
}
return $isZero{ $_ } if exists $isZero{ $_ };
die "Don't know";
}
print "$_ : ", isZero( $_ ) for @true;
print "$_ : ", isZero( $_ ) for @false;
As it can be infinitely extended to deal with any set of illogical rules.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
|
|
There is one point, in "0.0"
| [reply] |
|
Any definition that deems "0" as zero, but "00", "0.0" & "0 " as not, is so arbitrary
Please, take that up with Larry Wall. It isn't my fault that he considered "0" to be false, but "00", "0.0" & "0 " to be true. But then, that guy is well known for his arbitrary decisions which he never entertains any argument with, rendering the entire Perl language pointless.
| [reply] |
|
C:\test>perl -e"print '00' == 0"
1
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
|
|
Certainly is interesting that quoted 00 is true while quoted 0 is false (but it sounds like '0', "0" are special cases).
perl -E 'say 0 ? q{true} : q{false}' # false
perl -E 'say 00 ? q{true} : q{false}' # false
perl -E 'say q{0} ? q{true} : q{false}' # false
perl -E 'say qq{0} ? q{true} : q{false}' # false
perl -E 'say q{00} ? q{true} : q{false}' # true
perl -E 'say qq{00} ? q{true} : q{false}' # true
Perl 5.10.1 on Solaris 10 SPARC.
Elda Taluta; Sarks Sark; Ark Arks
| [reply] [d/l] |
Re: Determining whether a value is zero.
by choroba (Cardinal) on Mar 10, 2011 at 12:30 UTC
|
The dualvar part was hard :)
| [reply] [d/l] |
|
You don't want <readmore></readmore> , it is for larger content; you want
| [reply] [d/l] [select] |
|
| [reply] |
|
|
|
Close, but it reports dualvar (0, "0 ") not to be a zero.
| [reply] [d/l] |
|
You only defined the expected values for
Scalar::Util::dualvar 0, 1;
Scalar::Util::dualvar 1, 0;
So the effect you mentioned seems to be a specification-issue ;-)
| [reply] [d/l] |
|
I give up. I cannot tell dualvar 0,"0 " from "0 ":
use Devel::Peek;
use Scalar::Util qw/dualvar/;
my @x = ("0 ",dualvar(0,"0 "));
(10.2+$_).$_ for @x;
Dump $x[0];
Dump $x[1];
gives SV = PVNV(0x830ef78) at 0x8310564
REFCNT = 1
FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x835465c "0 "\0
CUR = 2
LEN = 4
SV = PVNV(0x830ef8c) at 0x8310584
REFCNT = 1
FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x833b77c "0 "\0
CUR = 2
LEN = 4
| [reply] [d/l] [select] |
|
|
Re: Determining whether a value is zero.
by ikegami (Patriarch) on Mar 11, 2011 at 05:04 UTC
|
use B qw( svref_2object SVf_IOK SVf_NOK SVf_POK );
sub is_zero {
my $sv = svref_2object(my $ref = \$_[0]);
my $flags = $sv->FLAGS;
return $sv->IVX == 0 if $flags & SVf_IOK;
return $sv->NVX == 0 if $flags & SVf_NOK;
return $sv->PV eq "0" if $flags & SVf_POK;
return 0;
}
| [reply] [d/l] |
|
| [reply] |
|
If there's a way to do it without having to break encapsulation of value and peek at their internal flags, I don't know such a way - but I'd love to hear about it.
Tried and failed. Need to find something that can distinguish between absent IV and NV and zero IV or NV. This boils down to finding something that
- favours IV and NV over PV, and
- doesn't silently numify the PV if it looks_like_number.
Lots of operations match the first requirement (arithmetic and bitwise ops) but I can't think of anything that matches both.
| [reply] |
|
To be fair, I would have mentioned something about the rules not being practical if it hadn't already been said. In case you were actually planning on using this and didn't realize the consequences.
| [reply] |
|
isn't dualvar's made by peeking at the internals ? I think it's unfair to try to detect something without the same techniques used to create that something, but hey it's your challenge.
On a unrelated note, is dualvar(undef,"string") zero ?
| [reply] [d/l] [select] |
|
|
It works only if I do not touch (i.e. expose it to various contexts) the variable before running the test:
for my $x (0,
"0",
0.0,
dualvar(0,1),
dualvar(0,"0 "),
'----------------',
1,
"foo",
"00",
"0 ",
undef,
"",
dualvar(1,0),
"0.0",
) {
print "$x before: ",is_zero($x),"\n";
my $y = ($x+1.1).$x;
print "$x after: ",is_zero($x),"\n";
}
| [reply] [d/l] |
|
0+$x; #Upd: Or 1.1 or whatever
is effectively
$x = dualvar(0+$x, $x) if looks_like_number($x);
The OP was clear that dualvar(0, $anything) should be considered zero.
| [reply] [d/l] [select] |
|
|
|
|
|
|
It works only if I do not touch (i.e. expose it to various contexts) the variable before running the test:
Well, yes. That's because looking at variables in Perl can actually modify them.
| [reply] |
|
Some notes:
It could be considered to break the pure Perl rule. B is written in XS. But hey, so are operators and both come with Perl.
It doesn't call get magic or handle overloading.
| [reply] |
Re: Determining whether a value is zero.
by raybies (Chaplain) on Mar 10, 2011 at 13:43 UTC
|
And what about -0.0 ;which, at least on my linux box, is a valid value in Perl? --Ray
| [reply] |
|
FYI, the IEEE floating point standard requires support for positive and negative zero. See Signed_Zero and IEEE_754 for more. So more like a "most computers and programming languages" thing than a Perl thing.
Elda Taluta; Sarks Sark; Ark Arks
| [reply] |
|
I'll accept either way, under the condition it's consistent with what you'd return on dualvar(-0.0, ...)
| [reply] [d/l] |