Для проекта мне нужно прочитать информацию из MQTT. Полезная нагрузка заполнена информацией protobuf, которая должна быть преобразована.
Для определенного значения я получаю 5.6904566139035E-28 как float. С помощью http://www.exploringbinary.com/floating-point-converter/ Я могу преобразовать это, когда я отмечу одно и шестнадцатеричное значение, а затем получаю 12345678, значение, которое я должен иметь (я знаю, что отправлено).
Но теперь мне нужно сделать это преобразование в PHP. Я понятия не имею, как это можно сделать. После некоторого прочтения я понял, что это число с плавающей запятой, но как конвертировать это, как на этом сайте.
Есть ли кто-то, кто может помочь мне с этим!
Большое спасибо!
С довольно загадочным пак а также распаковывать функции, это можно сделать в одну строку:
function rawSingleHex($num) {
return strrev(unpack('h*', pack('f', $num))[1]);
}
это «пакеты» число как его двоичное представление, то «распаковывается» это в массиве с одним элементом: двоичное представление в шестнадцатеричном формате. Этот формат имеет цифры в обратном порядке, поэтому функция меняет их в конечном результате.
Позвоните, передав число с плавающей запятой:
echo rawSingleHex(5.6904566139035E-28);
Выход:
12345678
(это был мой первоначальный ответ, но при наличии первого варианта это не рекомендуемый способ продолжить)
Бинарный формат объясняется в статье Википедии о Формат с плавающей запятой одинарной точности.
Вот функция PHP, которая реализует описанную процедуру:
function rawSingleHex($num) {
if ($num == 0) return '00000000';
// set sign bit, and add another, higher one, which will be stripped later
$sign = $num < 0 ? 0x300 : 0x200;
$significant = abs($num);
$exponent = floor(log($significant, 2));
// get 24 most significant binary bits before the comma:
$significant = round($significant / pow(2, $exponent-23));
// exponent has exponent-bias format:
$exponent += 127;
// format: 1 sign bit + 8 exponent bits + 23 significant bits,
// without left-most "1" of significant
$bin = substr(decbin($sign + $exponent), 1) .
substr(decbin($significant), 1);
// assert that result has correct number of bits:
if (strlen($bin) !== 32) {
return "unexpected error";
}
// convert binary representation to hex, with exactly 8 digits
return str_pad(dechex(bindec($bin)), 8, "0", STR_PAD_LEFT);
}
Он выводит так же, как в первом решении.
Других решений пока нет …