Существует разница между тем, что хранится в переменной 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
. Это еще одна причина, чтобы всегда use warnings
в ваших Perl скриптов, так что сравнивать нечисловое строку с ==
будет набрать это предупреждение:
Argument "asdf" isn't numeric in numeric eq (==) at -e line 1.
'$ price * 100 + 0.5', вероятно, не будет делать то, что вы ожидаете, если вы ожидаете округления. С '$ price = 8.5' эта часть уравнения даст' 850.5'. – TLP
Запустите 'perl -e 'printf"% .2f ", 8.505'', чтобы увидеть, что вы делаете неправильно. – mob
Вы сбрасываете '$ price' и' $ lsec', но это не цифры, которые вы сравниваете. –