В чем причина этой ошибки форматирования Perl? - PullRequest
2 голосов
/ 12 ноября 2010
$str =sprintf "%014ld", "2555600000";
print $str;

Это дает мне результат:

-0001739367296

отрицательное число.Есть ли причина для такого поведения?

Ответы [ 3 ]

11 голосов
/ 12 ноября 2010

2555600000 слишком велик, чтобы поместиться в 32-разрядное целое число со знаком.Преобразованный в двоичный код, это 10011000 01010011 01011100 10000000, что означает -0001739367296, когда интерпретируется как 32-разрядное целое число со знаком.

Ваши параметры:

my $str = sprintf("%014u", 2555600000);     # unsigned integer
my $str = sprintf("%014.0f", 2555600000);   # floating point
my $str = sprintf("%014s", 2555600000);     # string

Первый из них работает для этогономер, но не для гораздо больших чисел.Второй может стать неточным для очень больших чисел.(Но со стандартной плавающей точкой «double» вы должны легко быть точными для 14 цифр, которые вы используете. Третья может быть самой простой, просто трактуйте ее как строку и забудьте, что это число.

Чтобы увидеть, сколько битов использует ваша версия, вы можете запустить perl -V. Пример вывода:

...
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
...

, поэтому мой Perl использует 4-байтовые 32-битные целые числа.

5 голосов
/ 12 ноября 2010
$ perl -e '$str =sprintf "%014ld", "2555600000"; print $str, "\n";'
00002555600000

Это работает для меня.Однако число, которое вы даете, превышает 32-разрядное целое число со знаком, так что, возможно, ваш результат означает, что вы находитесь на 32-разрядном компьютере?

4 голосов
/ 12 ноября 2010

К сожалению, модификаторы printf довольно тесно связаны с базовыми типами C (хотя размеры определяются perl - ld ничем не отличается от d, ниже perl будет использовать размер квалификатора int, для которого он построен).

Таким образом,% d преобразует число в целое число со знаком,% u в целое число без знака, даже если perl знает, что это на самом деле.

Вам часто лучше использовать% s:

$ perl -wle'printf "%014s\n%014d\n", "2555600000", "2555600000";'
00002555600000
-0001739367296
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...