Я пытаюсь преобразовать десятичное число, например
-268427136
в двоичном и наоборот.
Если я пытаюсь с Windows Calc, двоичная запись для этого числа:
1111111111111111111111111111111111110000000000000010000010000000
Если я попробую bindec, decbin или base_convert:
echo(decbin(-268427136));
Выходы:
11110000000000000010000010000000
Или же echo(bindec('1111111111111111111111111111111111110000000000000010000010000000');
Выходы:
1.84467440734E + 19
Что я могу использовать в php для достижения того же результата?
Ваш PHP, вероятно, скомпилирован для 32-битных систем, что приводит к переполнению целого числа и представлению числа в 32-битной системе. Убедитесь, что ваш PHP скомпилирован для 64-битной.
Вы можете проверить это с
<?php
echo PHP_INT_SIZE;
это должно вернуться 8
, На моем PHP следующее работает как PHP_INT_SIZE 8:
php > echo(decbin(-268427136));
1111111111111111111111111111111111110000000000000010000010000000
PHP использует тип языка C long
внутренне представлять целые числа (PHP написан на C). Это зависит от платформы. В 64-битной системе обычно это 64-битная длина. В Windows иногда такие приложения, как PHP, компилируются для 32-битной, несмотря на систему, поддерживающую 64-битную, что приводит к long
являющийся 32bit
или же 4byte
, Таким образом, вы получаете переполнение, которое приводит к 32-битному длинному числу. В твоем случае: 11110000000000000010000010000000
Согласно руководству по PHP, BinDec возвращает номер. Поскольку ваш номер 64-битный, PHP интерпретирует его как число с плавающей точкой. Он рассчитывает отсечение для использования целого числа или числа с плавающей запятой без знака. Увидеть 2.
php > var_dump(bindec('1111111111111111111111111111111111110000000000000010000010000000'));
float(1.8446744073441E+19)
Это можно предотвратить путем явного приведения к int
,
php > var_dump((int)bindec('1111111111111111111111111111111111110000000000000010000010000000'));
int(-268427264)
Других решений пока нет …