参数传递几次并不罕见.
这是一个有趣的例子,失去报价实际上可以帮助.
第一个abs()返回一个没有引号的变量,使第二个abs返回正确的值.
我的问题是:
perl是否有一个内部函数来取消引用变量,这样我就不用这样编码了?
#!/usr/bin/perl -w
use strict;
my @nums = (
'-0',
'-0.0',
"-0.000",
qw(-0.000),
sprintf("%.4f", "-0.0"),
);
print "***use single abs()\n";
foreach my $num(@nums){
my $number = $num;
my $abs = abs($number);
print "<$num> abs <$abs>\n";
}
print "\n***use abs(abs())\n";
foreach my $num(@nums){
my $abs_abs = abs(abs($num));
print "<$num> double abs <$abs_abs>\n";
}
Run Code Online (Sandbox Code Playgroud)
系统信息:
uname -r
2.6.32-573.12.1.el6.centos.plus.x86_64
This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi
Run Code Online (Sandbox Code Playgroud)
屏幕输出:
***use single abs()
<-0> abs <0>
<-0.0> abs <-0>
<-0.000> abs <-0>
<-0.000> abs <-0>
<-0.0000> abs <-0>
***use abs(abs())
<-0> double abs <0>
<-0.0> double abs <0>
<-0.000> double abs <0>
<-0.000> double abs <0>
<-0.0000> double abs <0>
Run Code Online (Sandbox Code Playgroud)
这不是引号的问题 - 引号只是Perl语法告诉解释器字符串的开始和结束位置.Perl知道存储的值是一个字符串,但引号本身不存储在内存中.
相反,它是特殊浮点值"-0.0"的工件.对于几乎任何用途,它相当于值0.0
perl -E ' $p = 0.0; $n = -0.0; say $p == $n ' ==> 1
perl -E ' $p = 0.0; $n = -0.0; $x = 4.2; say $p+$x == $n+$x ' ==> 1
Run Code Online (Sandbox Code Playgroud)
据我所知,两个例外是它们的二进制表示和它们的字符串表示.
$ perl -e 'print pack "F",0.0' | od -c
0000000 \0 \0 \0 \0 \0 \0 \0 \0
0000010
$ perl -e 'print pack "F",-0.0' | od -c
0000000 \0 \0 \0 \0 \0 \0 \0 200
0000010
$ perl -MDevel::Peek -e 'Dump($n=-0.0),Dump($p=0.0)'
SV = NV(0x43523d8) at 0x434ff00
REFCNT = 1
FLAGS = (NOK,pNOK)
NV = -0
SV = NV(0x43523e0) at 0x4329b58
REFCNT = 1
FLAGS = (NOK,pNOK)
NV = 0
$ perl -E '$p=0.0; $n=-0.0; say for $p,$n'
0
-0
Run Code Online (Sandbox Code Playgroud)
(实际上,使用Perl v5.12我看到0,-0但是v5.16是0,0- 可能是有人注意到并修复了它)
整数0并-0没有这个问题.
abs(-0.0)返回整数0,所以它abs似乎是偶然的,似乎解决了这个"引用"问题.