if( (sprintf("%.2f", ($price*100+0.5)/100)*1 != $lsec*1) )
{
print Dumper($price,$lsec)
}
有时翻斗车打印相同的数字(作为字符串)并跳入。 想到,乘以1可以使它们浮起......
这里的转储输出:
$VAR1 = '8.5';
$VAR2 = '8.5';
我做错了什么?
谢谢,
问候和复活节快乐。
答案 0 :(得分:4)
Perl变量中存储的内容与的使用方式之间存在差异。你是正确的,乘以1迫使一个变量使用作为数字。它还会将数字存储在代表解释器变量的SV
数据结构中。您可以使用Devel::Peek
模块查看Perl在每个变量中存储的内容:
use Devel::Peek;
my $num = "8.5";
Dump $num;
输出:
SV = PV(0xa0a46d8) at 0xa0c3f08
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0xa0be8c8 "8.5"\0
CUR = 3
LEN = 4
...继续
my $newnum = $num * 1;
Dump $num;
Dump $newnum;
输出:
SV = PVNV(0xa0a46d8) at 0xa0c3f08
REFCNT = 1
FLAGS = (PADMY,NOK,POK,pIOK,pNOK,pPOK)
IV = 8
NV = 8.5
PV = 0xa0be8c8 "8.5"\0
CUR = 3
LEN = 4
SV = NV(0x9523660) at 0x950df20
REFCNT = 1
FLAGS = (PADMY,NOK,pNOK)
NV = 8.5
我们关注的属性是PV
(字符串指针),NV
(浮点数)和IV
(整数)。最初,$num
仅具有字符串值,但将其用作数字(例如,在乘法中)会使其存储数值。但是,$num
仍然“记住”它是一个字符串,这就是Data::Dumper
将其视为一个字符串的原因。
对于大多数用途,不需要显式强制使用字符串作为数字,因为运算符和函数可以以最合适的形式使用它们。例如,==
和!=
运算符将其操作数强制转换为数字形式以进行数值比较。使用eq
或ne
强制进行字符串比较。这是在Perl脚本中始终use warnings
的另一个原因,因为尝试将非数字字符串与==
进行比较会收到此警告:
Argument "asdf" isn't numeric in numeric eq (==) at -e line 1.
答案 1 :(得分:3)
你说将字符串乘以1将强制将其作为数字进行求值是正确的,但数字!=
比较器将执行相同的操作。这可能是你从其他语言中获得的一种技术,因为Perl通常会执行正确的事情,并且不需要强制执行任何一个操作数。
让我们来看看你要比较的价值观点:
use strict;
use warnings;
use Data::Dumper;
my $price = '8.5';
my $lsec = '8.5';
my $rounded_price = sprintf("%.2f", ($price * 100 + 0.5) / 100);
print "$rounded_price <=> $lsec\n";
if ( $rounded_price != $lsec ) {
print Dumper($price,$lsec);
}
<强>输出强>
8.51 <=> 8.5
$VAR1 = '8.5';
$VAR2 = '8.5';
所以Perl正确地说8.51不等于8.5。
我怀疑你的
($price * 100 + 0.5) / 100
旨在将$price
舍入到两位小数,但事实上它只是将$price
增加0.005。我想你打算写
int($price * 100 + 0.5) / 100
但你也把价值放在sprintf
这是另一种做同样事情的方法。
要么
$price = int($price * 100 + 0.5) / 100
或
$price = sprintf ".2f", $price
但两者都是矫枉过正的!
答案 2 :(得分:1)
这部分:
($price*100+0.5)/100)
如果您输入8.5,则返回8.505。其中自然不等于8.5。由于您未更改$price
,因此您没有发现任何差异。
Perl自动处理转换,因此您无需担心。
my $x = "8.5";
my $y = 8.5;
print "Equal" if $x == $y; # Succeeds
比较的性质==
或您的案例!=
将参数转换为数字,无论它们是否为数字。
答案 3 :(得分:-3)
你没有做错任何事。 Perl在转储之前将其转换为字符串。要进行比较,请使用==
和!=
进行数字比较,使用eq
和ne
进行字符串比较。 Perl根据需要转换为字符串和数字。
示例:
$ perl -MData::Dumper -e "my $a=3.1415; print Dumper($a);"
$VAR1 = '3.1415';