PHP: как преобразовать bigint из int в строку?

Я хочу иметь возможность конвертировать большие целые числа в их полные строковые производные.

Например.

$bigint = 9999999999999999999;
$bigint_string = (string) $bigint;
var_dump($bigint_string);

выходы

string(7) "1.0e+19"

но мне нужно

string(19) "9999999999999999999"

Пожалуйста, не говорите мне, что я должен изначально установить значение $bigint в виде строки. Это не вариант. Я действительно застрял и не знаю, возможно ли это вообще?


person buggedcom    schedule 22.08.2011    source источник
comment
Точность потеряна. Это вне досягаемости для поплавка. Вы не получите желаемую строку вывода.   -  person mario    schedule 22.08.2011
comment
Я предполагаю, что единственный способ действительно состоит в том, чтобы изначально использовать строку. яйца.   -  person buggedcom    schedule 22.08.2011
comment
Возможно, вы получили бы более релевантные ответы, если бы вы объяснили вариант использования, а не то, что, по вашему мнению, хотите.   -  person mario    schedule 22.08.2011
comment
Я не вижу целого числа в вашем коде. Где это должно быть?   -  person hakre    schedule 22.08.2011
comment
@hakre - извините. Я не понимал, что большой int будет числом с плавающей запятой. Я никогда раньше не имел дело с такими большими числами.   -  person buggedcom    schedule 22.08.2011


Ответы (4)


На самом деле вы должны убедиться, что вы вводите то, что имеете в виду:

$bigint = 9999999999999999999;

Является не целым числом PHP, а числом с плавающей запятой:

float(1.0E+19)

Если бы ты сделал

$bigint = (int) 9999999999999999999;

На самом деле вы бы установили целое число, но это было бы не то число, которое вы могли бы ожидать:

int(-8446744073709551616)

Превратить это в строку совсем не проблема, как вы могли догадаться. Так что следите за тем, чтобы когда вы записываете числа в код, вы действительно писали то, что имеете в виду.

Посмотрите еще раз на эту строку:

$bigint = 9999999999999999999;

попытайтесь понять, что вы на самом деле написали. Это вовсе не целое число, потому что PHP превратит его в число с плавающей запятой. См. Пример #4 Целочисленное переполнение в 64-битной системе на странице руководства по целочисленным вычислениям.

Если вам нужна более высокая точность, ознакомьтесь с GNU Multiple Precision. ищу. Однако это не изменит способ записи чисел в PHP:

$bigint = gmp_init("9999999999999999999");
$bigint_string = gmp_strval($bigint);
var_dump($bigint, $bigint_string);

Выход:

resource(4) of type (GMP integer)
string(19) "9999999999999999999"
person hakre    schedule 22.08.2011
comment
Спасибо hakre за подробный ответ. Думаю, мне еще многому предстоит научиться. - person buggedcom; 22.08.2011
comment
gmp_init() должен начинаться со строки или целого числа, а не с плавающей запятой. Это означает, что если вы уже получили его в виде строки или целого числа, вам не нужен gmp. - person Alex Howansky; 22.08.2011
comment
@buggedcom: Пожалуйста. Всегда есть чему поучиться ;) - person hakre; 22.08.2011
comment
это не сработает, если вы передадите это так: $bigint = gmp_init(9999999999999999999); - person Phill Pafford; 04.11.2011
comment
@PhillPafford: передайте число как целое число или строку, а не с плавающей запятой. - person hakre; 05.11.2011
comment
@Alex Howansky: Ну, вы не можете выполнять целочисленные операции со строками в PHP, если они превышают целочисленный предел PHP, но gmp может. - person hakre; 05.11.2011
comment
@hakre: Да, но здесь есть уловка-22. В этом конкретном вопросе ОП не выполняет операции, ему просто нужно строковое представление большого числа int. Ему пришлось бы передать строку gmp_init(), чтобы получить ее. Это означает, что ему придется инициализировать функцию той самой строкой, которую он хотел получить. То есть ваш пример требует, чтобы у него было значение в строковом формате в первую очередь, и если бы это было так, то у него уже было бы то, что он искал, и ему не понадобился бы gmp. (Конечно, неясно, откуда берется начальное значение, так что... кто знает... :) - person Alex Howansky; 05.11.2011
comment
Ну, источник должен быть строкой. Разве не вся входная строка PHP? - person hakre; 05.11.2011

Используйте 1_.

echo strval($bigint); // Will output "99999999999999999"

РЕДАКТИРОВАТЬ: После немного лучшего исследования (> 5000 мс) я вижу, что невозможно повторить числа с такой точностью, потому что PHP не может сохранить целое число такого размера (зависит от битовой системы ОС, 32/64). Кажется, что это невозможно сделать без потери точности.

person Madara's Ghost    schedule 22.08.2011
comment
@Evan ;) 5 секунд поиска в Google. - person Madara's Ghost; 22.08.2011
comment
извините, это то же самое, что и преобразование в строку с помощью (string), и это не работает. Он просто выведет 1.0E+19 - person buggedcom; 22.08.2011
comment
На самом деле он вызывает _toString(), что не одно и то же. Но strval должно было сработать. - person Evan Mulawski; 22.08.2011
comment
@Evan - какую версию PHP вы используете для работы? Вы сами тестировали? - person buggedcom; 22.08.2011
comment
@Рикудо, спасибо. Наверное, раньше я не очень понимал, что такое потеря точности. - person buggedcom; 22.08.2011
comment
@buggedcom: это не будет работать в 64-битных системах. Из-за целочисленного переполнения это не всегда возможно. - person Evan Mulawski; 22.08.2011
comment
Однако вы можете использовать сторонние библиотеки. См. stackoverflow.com/questions/211345/< /а> - person Evan Mulawski; 22.08.2011
comment
@марио: правильно. Я пропустил нет. - person Evan Mulawski; 22.08.2011

Используйте printf(), он создан для этого:

echo printf("%d", $bigint);
person Arnaud Le Blanc    schedule 22.08.2011
comment
Это не работает для значений больше 32 бит. (Или 64, в любом случае.) - person Alex Howansky; 22.08.2011

Просто сохраните значение в виде строки и отобразите...!

   $bigint = '9999999999999999999';

    var_dump($bigint);

Выход:

string(19) "9999999999999999999"
person ShivarajRH    schedule 24.05.2013