У меня есть большие значения HEX, которые я хочу отображать как обычные числа, я использовал hexdec () для преобразования в float, и я нашел функцию на PHP.net, чтобы преобразовать ее в десятичную, но, похоже, она попадает в потолок, например :
$h = 'D5CE3E462533364B'; $f = hexdec($h); echo $f .' = '. Exp_to_dec($f);
Выход: 1,5406319846274E + 19 = 15406319846274000000
Результат от calc.exe = 15406319846273791563
Есть ли другой способ преобразования больших шестнадцатеричных значений?
Как сказано на странице руководства hexdec :
Теперь функция может преобразовывать значения, которые являются большими для целочисленного типа платформ, в этом случае вместо этого будет возвращено значение как float.
Если вы хотите получить какое-то большое целое число (не плавать), вам понадобится его хранить внутри строки. Это может быть возможно с использованием функций BC Math .
Например, если вы посмотрите в комментариях на странице руководства hexdec, вы найдете эту заметку
Если вы немного адаптируете эту функцию, чтобы избежать уведомления, вы получите:
function bchexdec($hex) { $dec = 0; $len = strlen($hex); for ($i = 1; $i <= $len; $i++) { $dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i)))); } return $dec; }
(Эта функция была скопирована из примечания, к которой я привязан, и только немного адаптирована мной)
И используя его на вашем номере:
$h = 'D5CE3E462533364B'; $f = bchexdec($h); var_dump($f);
Выход будет:
string '15406319846273791563' (length=20)
Итак, не такой большой поплавок, который у вас был; и, кажется, все в порядке с тем, что вы ожидаете:
Результат от calc.exe = 15406319846273791563
Надеюсь эта помощь 😉
И, да, примечания пользователя по документации PHP иногда представляют собой настоящую золотую жилу 😉
hexdec () переключается с int на float, когда результат слишком велик, чтобы быть представленным как int. Если вы хотите произвольно длинные значения, вам, вероятно, придется перевернуть свою собственную функцию преобразования, чтобы изменить шестнадцатеричную строку на целое число GMP .
function gmp_hexdec($n) { $gmp = gmp_init(0); $mult = gmp_init(1); for ($i=strlen($n)-1;$i>=0;$i--,$mult=gmp_mul($mult, 16)) { $gmp = gmp_add($gmp, gmp_mul($mult, hexdec($n[$i]))); } return $gmp; } print gmp_strval(gmp_hexdec("D5CE3E462533364B")); Output: 15406319846273791563
1.5406319846274E + 19 – ограниченное представление вашего номера. Вы можете иметь более полную версию, используя printf ()
printf("%u\n", hexdec($h));
… выведет «15406319846273792000». PHP использует поплавки для таких больших чисел, поэтому вы можете потерять немного точности. Если вам нужно работать с произвольными точками точности, вы можете попробовать расширение bcmath . Разделив гексагон на два 32-битных слова (которые должны быть безопасными для большинства систем), вы сможете получить больше точности. Например:
$f = bcadd(bcmul(hexdec(substr($h, 0, -8)), 0x100000000), hexdec(substr($h, 8)));
… установил бы $ f до 15406319846273791563.
Преобразование HEX в DEC легко .. Но восстановить шестнадцатеричное число назад очень сложно. Попробуйте использовать base_convert ..
$hexadecimal = base_convert(2826896153644826, 10, 16); // result: a0b0c0d0e0f1a
$num = gmp_init( '0xD5CE3E462533364B' ); // way to input a number in gmp echo gmp_strval($num, 10); // display value in decimal
Это модуль для использования. Преобразуйте его в функцию, а затем используйте на своих номерах.
Примечание: укажите эти шестнадцатеричные числа как строки так:
$num = "0x348726837469972346"; // set variable $gmpnum = gmp_init("$num"); // gmp number format echo gmp_strval($gmpnum, 10); // convert to decimal and print out
Запустите эту проблему при сохранении 64-битных ключей в базе данных MySQL. Мне удалось получить отличное преобразование в 64-разрядное целое число со знаком (ограничение PHP) с использованием нескольких бинарных операторов: (Этот код в 16 раз быстрее, чем функция bchexdec, а результирующие переменные используют в среднем половину памяти).
function x64toSignedInt($k){ $left = hexdec(substr($k,0,8)); $right = hexdec(substr($k,8,8)); return (int) ($left << 32) | $right; }
Подписанный MySQL тип данных BIGINT отлично подходит для этого как индекс или хранилище в целом. HEX (столбец) – это простой способ преобразовать его обратно в HEX в SQL-запросе для использования в другом месте.
Разве intval(var, base)
не заботится об этом?
Из руководства по PHP .