请问有人可以帮助我解决以下情况吗?我正在尝试比较 $price 和 $lsec。
if( (sprintf("%.2f", ($price*100+0.5)/100)*1 != $lsec*1) )
{
print Dumper($price,$lsec)
}
Run Code Online (Sandbox Code Playgroud)
有时,转储程序会打印相同的数字(作为字符串)并跳入。认为,与 1 相乘会使它们成为浮点数......
这里转储器输出:
$VAR1 = '8.5';
$VAR2 = '8.5';
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
谢谢你,
问候和复活节快乐。
Perl 变量中存储的内容和使用它的方式是有区别的。您是正确的,乘以 1 会强制将变量用作数字。它还导致数字存储在SV向解释器表示变量的数据结构中。您可以使用该Devel::Peek模块查看 Perl 在每个变量中存储的内容:
use Devel::Peek;
my $num = "8.5";
Dump $num;
Run Code Online (Sandbox Code Playgroud)
输出:
SV = PV(0xa0a46d8) at 0xa0c3f08
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0xa0be8c8 "8.5"\0
CUR = 3
LEN = 4
Run Code Online (Sandbox Code Playgroud)
继续...
my $newnum = $num * 1;
Dump $num;
Dump $newnum;
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
我们关心的属性是PV(字符串指针)、NV(浮点数)和IV(整数)。最初,$num只有字符串值,但将其用作数字(例如在乘法中)会导致它存储数值。然而,$num仍然“记住”它是一个字符串,这就是为什么Data::Dumper将它视为一个字符串。
对于大多数目的,不需要显式强制使用字符串作为数字,因为运算符和函数可以以最合适的形式使用它们。例如, and 运算符将其操作数强制转换为数字形式以进行数字比较==。!=使用eqorne来强制进行字符串比较。这是始终在 Perl 脚本中的另一个原因use warnings,因为尝试将非数字字符串与 进行比较==将收到此警告:
Argument "asdf" isn't numeric in numeric eq (==) at -e line 1.
Run Code Online (Sandbox Code Playgroud)