Windows — Как напечатать 40-битное число в PHP, используя 32-битный компьютер

Я пытаюсь напечатать 40-битное число в php. Но при использовании компьютера с Windows он допускает только 32-разрядные целые числа, что приводит к тому, что мой код отображает неверный результат. Пример кода ниже:

function decoded_microchip_id($coded_string) {
$manufacturer = substr($coded_string, 0, 3);
$manufacturer = hexdec($manufacturer);
$manufacturer = $manufacturer / 4;
$device_id = substr($coded_string, 2, 11);
$device_id = hexdec($device_id);
$device_id = $device_id & 0x3fffffffff;
echo $manufacturer.'.'.$device_id;
};

decoded_microchip_id('f58e29a43c67');

Правильный вывод для кода выше: 982.60828171367

Но в моей 32-битной среде Windows я получаю: 982.698629223

При тестировании кода в различных песочницах PHP выходные данные также различаются.

Вот пример среды песочницы, дающей мне правильный вывод:
http://sandbox.onlinephpfunctions.com/code/83cc28fd5314557e7a9d86d8061e1c8dfae4d1b7

И вот пример среды, которая производит неправильный вывод:
http://codepad.org/m2ygOgC6

Кто-нибудь знает способ обойти эту проблему или решение.

Благодарю.

3

Решение

Функция PHP hexdec() отлично работает на 32-битной тоже. Документация говорит, что это производит float числа, когда результат не помещается в 32 бита.

Интересно что 0x3fffffffff также хранится как float число.

Виновником является побитовый оператор (&), который, кажется, производит целое число. Преобразование его результата в float не помогает, урон уже нанесен.

Такое поведение документированный:

оба операнда будут преобразованы в целые числа, а результатом будет целое число.

Потенциальное решение

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

Конкретный раствор

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

function decoded_microchip_id($coded_string)
{
// Convert to binary
$bin = base_convert($coded_string, 16, 2);
// Split to 10/38 bits
$manufacturer = substr($bin, 0, 10);
$device_id    = substr($bin, 10, 38);
// Convert to decimal
$manufacturer = bindec($manufacturer);
$device_id    = bindec($device_id);
// Put pieces back
return $manufacturer.'.'.$device_id;
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]