unary minus strangeness

S

sreservoir

% perl -E'say -0'
0
% perl -E'say -undef'
-0
% perl -E'say(("-0")? 1 : 0)'
1
% perl -E'say((-undef)? 1 : 0)'
0
% perl -E'say ref -undef'


what is a -0 supposed to be and why does undef evaluate to it? it is
apparently not the string "-0", nor is it a ref with that string value;
is this some sort of magical trickery?
 
J

John W. Krahn

sreservoir said:
% perl -E'say -0'
0
% perl -E'say -undef'
-0
% perl -E'say(("-0")? 1 : 0)'
1
% perl -E'say((-undef)? 1 : 0)'
0
% perl -E'say ref -undef'


what is a -0 supposed to be and why does undef evaluate to it? it is
apparently not the string "-0", nor is it a ref with that string value;
is this some sort of magical trickery?

perldoc perlop
[ SNIP ]
Symbolic Unary Operators
Unary "!" performs logical negation, i.e., "not". See also "not"
for a lower precedence version of this.

Unary "-" performs arithmetic negation if the operand is numeric.
^^^^^^^^^^^^^^^^^^^^^^^^^
[ *undef is not numeric.* ]

If the operand is an identifier, a string consisting of a minus
sign concatenated with the identifier is returned. Otherwise, if
the string starts with a plus or minus, a string starting with
the opposite sign is returned. One effect of these rules is that
-bareword is equivalent to the string "-bareword". If, however,
the string begins with a non-alphabetic character (excluding "+"
or "-"), Perl will attempt to convert the string to a numeric and
the arithmetic negation is performed. If the string cannot be
cleanly converted to a numeric, Perl will give the warning
Argument "the string" isn’t numeric in negation (-) at ....



John
 
S

sreservoir

sreservoir said:
% perl -E'say -0'
0
% perl -E'say -undef'
-0
% perl -E'say(("-0")? 1 : 0)'
1
% perl -E'say((-undef)? 1 : 0)'
0
% perl -E'say ref -undef'


what is a -0 supposed to be and why does undef evaluate to it? it is
apparently not the string "-0", nor is it a ref with that string value;
is this some sort of magical trickery?

perldoc perlop
[ SNIP ]
Symbolic Unary Operators
Unary "!" performs logical negation, i.e., "not". See also "not"
for a lower precedence version of this.

Unary "-" performs arithmetic negation if the operand is numeric.
^^^^^^^^^^^^^^^^^^^^^^^^^
[ *undef is not numeric.* ]

If the operand is an identifier, a string consisting of a minus
sign concatenated with the identifier is returned. Otherwise, if
the string starts with a plus or minus, a string starting with
the opposite sign is returned. One effect of these rules is that
-bareword is equivalent to the string "-bareword". If, however,
the string begins with a non-alphabetic character (excluding "+"
or "-"), Perl will attempt to convert the string to a numeric and
the arithmetic negation is performed. If the string cannot be
cleanly converted to a numeric, Perl will give the warning
Argument "the string" isn’t numeric in negation (-) at ....

you would think that would mean -'' would be '-'. but no, it's also
-0. you're kind of making my point.
 
B

Bo Lindbergh

For real strangeness, you need to mix negative zero, boolean context,
and stringification.

{
my $strange=-0.0;
print $strange ? "$strange is true\n" : "$strange is false\n";
print $strange ? "$strange is true\n" : "$strange is false\n";
}


/Bo Lindbergh
 
I

Ilya Zakharevich

For real strangeness, you need to mix negative zero, boolean context,
and stringification.

{
my $strange=-0.0;
print $strange ? "$strange is true\n" : "$strange is false\n";
print $strange ? "$strange is true\n" : "$strange is false\n";
}

This is a bug. Read-only access should not change the value.

Yours,
Ilya
 
M

Marc Girod

For some reason, undef gets numified as a floating-point
zero rather than an integral zero, so it can be negated.

May I check that I understand this with respect to the excerpt of
perlop John gave:

$ perl -E'say undef'

$ perl -E'say q()'

$ perl -E'say -undef'
-0
$ perl -E'say -q()'
0
$ perl -E'say "-undef"'
-undef
If the operand is an identifier, a string consisting of a minus
sign concatenated with the identifier is returned.

So, not this case:
undef is not an 'identifier', and the return is no '-undef'.
Otherwise, if the string starts with a plus or minus,
a string starting with the opposite sign is returned.
No.

One effect of these rules is that -bareword is equivalent
to the string "-bareword".
No.

If, however, the string begins with a non-alphabetic character
(excluding "+" or "-"), Perl will attempt to convert the
string to a numeric and the arithmetic negation is performed.

I understand that this is what applies: undef is a 'non-alphabetic
character'?
There, undef is converted to 'floating-point 0', whereas q() (the
empty string) is converted to 'integer 0'.
If the string cannot be cleanly converted to a numeric,
Perl will give the warning

No: no warning.

Thanks,
Marc
 
B

Bo Lindbergh

This is a bug. Read-only access should not change the value.

Would you call this example the same bug, a different bug, or not a bug?
{
my $strange="-0";
print "- $strange == ", -$strange, "\n";
my $ignored=0+$strange;
print "- $strange == ", -$strange, "\n";
}

Ditto for this one.
{
my($one,$two)=("12","21");
print "$one | $two == ", $one | $two, "\n";
my $ignored=$one+$two;
print "$one | $two == ", $one | $two, "\n";
}


/Bo Lindbergh
 
I

Ilya Zakharevich

.... Reading string value of -0.0 changes TRUE/FALSE...
Would you call this example the same bug, a different bug, or not a bug?
{
my $strange="-0";
print "- $strange == ", -$strange, "\n";
my $ignored=0+$strange;
print "- $strange == ", -$strange, "\n";
}

.... Reading NUM value of "-0" changes the effect of unary minus.

It looks like different bugs - but they may have the same fix.... ;-)
Ditto for this one.
{
my($one,$two)=("12","21");
print "$one | $two == ", $one | $two, "\n";
my $ignored=$one+$two;
print "$one | $two == ", $one | $two, "\n";
}

Not a bug - just a documented brokenness of |-operator...

Hope this helps,
Ilya
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,052
Latest member
LucyCarper

Latest Threads

Top