Вопрос

На 32-битной платформе Windows мне нужно прочитать некоторые цифры, которые, как это ни было неожиданно, могут иметь значения до 99 999 999 999, но не более. Попытка sprintf ("% 011d " ;, $ myNum) их приводит к переполнению: -2147483648.

Я не могу использовать модуль BigInt, потому что в этом случае я должен глубоко изменить код. Я не могу управлять форматом как строкой, sprintf ("% 011s " ;, $ Numberro) , поскольку знак минус обрабатывается неправильно.

Как я могу справиться с этим? Может ли упаковать / распаковать какую-нибудь помощь?

Это было полезно?

Решение

Попробуйте отформатировать его как число с плавающей точкой без дробной части:

$ perl -v
This is perl, v5.6.1 built for sun4-solaris
...

$ perl -e 'printf "%011d\n", 99999999999'
-0000000001

$ perl -e 'printf "%011.0f\n", 99999999999'
99999999999

Другие советы

Да, одно из числовых мертвых зон Perl - это форматирование; Perl автоматически обрабатывает представление чисел в виде целых чисел или с плавающей точкой, но затем приводит их к один или другой, когда используются числовые форматы printf , даже если это не так подходящее. И printf на самом деле вообще не обрабатывает BigInts (кроме как обработкой их в виде строк и преобразования их в число с потерей точности.

Использование% s вместо% d с любым числом, которое вы не уверены, будет в соответствующем Диапазон - хороший обходной путь, за исключением того, что вы заметили отрицательные числа. Обрабатывать те, вам придется написать некоторый код Perl.

Я не эксперт по Perl, и, возможно, мне здесь не хватает какой-то автоматической обработки бигнумов, но разве это не просто случай целочисленного переполнения? 32-разрядное целое число не может содержать числа размером более 99 999 999 999.

В любом случае, я получаю тот же результат с Perl v5.8.8 на моей 32-битной машине Linux, и кажется, что printf с "% d " не обрабатывает большие числа.

Я думаю, что ваша копия Perl должна быть сломана, это из версии CygWin (5.10):

pax$ perl -e 'printf("%011d\n", 99999999999);'
99999999999

pax$ perl -v

This is perl, v5.10.0 built for cygwin-thread-multi-64int
(with 6 registered patches, see perl -V for more detail)

Copyright 1987-2007, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

Какую версию вы используете (вывод perl -v )?

Возможно, вам придется получить 64-битную версию Perl [и, возможно, новую 64-битную рабочую машину] (обратите внимание на " cygwin-thread-multi-64int " в моих выходных данных. ). Это, по крайней мере, позволит избежать необходимости изменения кода.

Я утверждаю это на том основании, что вы не хотите сильно менять код (то есть боитесь что-то сломать). Решение нового оборудования, хотя и немного дорогое, почти наверняка не потребует от вас смены программного обеспечения вообще . Это зависит от ваших приоритетов.

Другая возможность состоит в том, что сам Perl может правильно хранить число, но просто отображать его неправильно из-за ошибки printf () . В этом случае вы можете попробовать:

$million = 1000000;
$bignum = 99999999999;
$firstbit = int($bignum / $million);
$secondbit = $bignum - $firstbit * million;
printf ("%d%06d\n",$firstbit,$secondbit);

Поместите это в функцию и вызовите функцию, чтобы вернуть строку, например:

sub big_honkin_number($) {
    $million = 1_000_000;
    $bignum = shift;
    $firstbit = int($bignum / $million);
    $secondbit = $bignum - $firstbit * $million;
    return sprintf("%d%06d\n", $firstbit, $secondbit);
}
printf ("%s", big_honkin_number (99_999_999_999));

Обратите внимание, что я тестировал это, но на 64-битной платформе - вам нужно будет провести свой собственный тест на 32-битной платформе, но вы можете использовать любой масштабный коэффициент, который вы хотите (включая более двух сегментов, если это необходимо).

Обновление . Этот трюк big_honkin_number () отлично работает на 32-битном Perl, так что похоже, что просто функции printf () , которые наполняют вас:

pax@pax-desktop:~$ perl -v

This is perl, v5.8.8 built for i486-linux-gnu-thread-multi

Copyright 1987-2006, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

pax@pax-desktop:~$ perl qq.pl
99999999999
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top