|
|
|
| Я пытаюсь получить десятичное представление бинарных данных. Где ошибка в функции "mybin2dec()"?
<?php
function mybin2dec($binary = "")
{
$result = "";
for($i = 0; $i < strlen($binary); $i++)
{
$num = unpack("Cint", $binary[$i]);
$result = bcadd($result, bcmul($num["int"], bcpow(2, bcsub(strlen($binary), bcadd($i, 1)))));
}
return $result;
}
function mydecbin($number = 0)
{
$result = "";
while(true)
{
$result .= bcmod($number, 2);
if(bccomp($number, 2) < 0) break;
$number = bcdiv($number, 2);
}
return strrev($result);
}
//Проверка
echo(mydecbin(mybin2dec("BinaryData")) . "\r\n"); //1001001000
echo(decbin(hexdec(bin2hex("BinaryData")))); //10000100110100101101110
//Ошибка
?>
|
| |
|
|
|
|
|
|
|
для: Unkind
(25.05.2007 в 18:24)
| | Функции ord и chr недостаточно?
[поправлено модератором] | |
|
|
|
|
|
|
|
для: Trianon
(25.05.2007 в 18:29)
| | К сожалению, нет. | |
|
|
|
|
|
|
|
для: Unkind
(25.05.2007 в 18:32)
| | Аргументации не последует?
функция unpack, применительно к одному байту - nop.
[поправлено модератором] | |
|
|
|
|
|
|
|
для: Trianon
(25.05.2007 в 18:34)
| | Аргументации не последует?
Я хочу перевести всю эту хрень бинарную в свою систему счисления, в которой много "цифр", чтобы сжать строку. Мне и не нужен один байт, а как раз наоборот.
Или это из разряда "преподаватель сказал сделать так!"?
Нет, это для себя. | |
|
|
|
|
|
|
|
для: Unkind
(25.05.2007 в 18:37)
| | Вы её переводите не в бинарную, а в текстовую.
function to_bin($x)
{
$s = "$x"; $t = '';
for($i = 0; $i < strlen($s); $i++)
$t .= str_pad(decbin(ord($s[$i])), 8, '0', STR_PAD_LEFT);
return $t;
}
в обратную сторону аналогично | |
|
|
|
|
|
|
|
для: Trianon
(25.05.2007 в 18:45)
| | Спасибо.
Вы её переводите не в бинарную, а в текстовую.
Эээ. А в чем различие? :) | |
|
|
|
|
|
|
|
для: Unkind
(25.05.2007 в 18:49)
| | 5 - это целое число, его машинное представление - такое:
00000101 00000000 00000000 00000000
'5' - это текстовая строка. её машинное представление примерно такое
00000001 000000101
"00110101" - это тоже текстовая строка. её машинное представление примерно такое
00001000 00000000 00000000 00000001 00000001 00000000 00000001 00000000 00000001 | |
|
|
|
|
|
|
|
для: Trianon
(25.05.2007 в 19:16)
| | OK, а как тогда можно сделать функцию, обратную моей mybin2dec()? | |
|
|
|
|
|
|
|
для: Unkind
(25.05.2007 в 19:32)
| | Расшифровать бы еще, что Вы такое в нее понапихали...
for($i = 0; $i < strlen($binary); $i++) {
$num = unpack("Cint", $binary[$i]);
$result = bcadd($result, bcmul($num["int"], bcpow(2, bcsub(strlen($binary), bcadd($i, 1))))); }
Фактически это равнозначно такому коду:
for($i = 0; $i < strlen($binary); $i++) {
$digit256 = ord($binary[$i]);
$result = bcadd($result, bcmul($digit256, bcpow(2, bcsub(strlen($binary), bcadd($i, 1))))); }
Последняя строка алгоритмически означает
$result += $digit256 << (N-1-$i);
То есть Вы добавляете байты (т.е. цифры по основанию 256), а сдвигаете их на биты.
Явно в алгоритме нестыковка.
Если бы $digit256 была двоичная цифра - всё бы сросталось.
Если бы bcpow(256 стоял - тоже всё бы сросталось. Хотя и далеко не так оптимально, как в моем варианте. А так - увы. | |
|
|
|
|
|
|
|
для: Trianon
(25.05.2007 в 21:36)
| | Не понимаю в чем тут может быть нестыковка. Перевод из строки "01", где ord("0") - 48, ord("1") - 49 в десятичное представление - по формуле a1 * b ^ (n-1) + a2 * b ^ (n-2) + ... + a(n-1) * b ^ 1 + an * b ^ 0, где n - основание той системы счисления из которой переводим:
<?php
function mybin2dec($binary = "")
{
$result = "";
/*
a1 * b^(n-1) + a2 * b^(n-2), где основание n = 2;
ord($binary[0]) * (2 ^ (2 - 1)) + ord($binary[1]) * (2 ^ (2 - 2));
48 * 2 + 49 * 1 = 145;
*/
for($i = 0; $i < strlen($binary); $i++)
{
$result = bcadd($result, bcmul(ord($binary[$i]), bcpow(2, bcsub(strlen($binary), bcadd($i, 1)))));
}
return $result;
}
var_dump(mybin2dec("01")); //string(3) "145"
?>
|
| |
|
|
|
|
|
|
|
для: Unkind
(25.05.2007 в 22:13)
| | нестыковка в вызове
mybin2dec("BinaryData") - вот тут вы собирались быть может строку с нулями и единицами написать. А написали - с латинскими буквами.
я решил что вы работаете со всеми восемью разрядами на символ.
Какие все ж таки строки будут преобразовываться? | |
|
|
|
|
|
|
|
для: Trianon
(25.05.2007 в 22:15)
| | '5' - это текстовая строка. её машинное представление примерно такое
00000001 000000101
Я хочу получить десятичное число из этой строки (по видимому 53).
И я хочу получить эту строку из получившегося ранее десятичного числа (53). | |
|
|
|
|
|
|
|
для: Unkind
(25.05.2007 в 22:21)
| | Допустим. А из строки
'25'
Вы хотите получить какое число и почему?
Длина строки 2, первый символ имеет машинное представление 50, второй - 53
с представлением '5' я наврал :) на самом деле конечно
000000001 00000000 00000000 00000000 00110101
первые четыре байта - длина (равная 1 символу) , пятый байт - двоичный код код 53 | |
|
|
|
|
|
|
|
для: Trianon
(25.05.2007 в 22:24)
| | какое число
153 (50 * 2 + 53 * 1)
почему
Длина строки будет маленькой, если выбрать систему счисления с большим количеством цифр. То есть это число 153 потом перевести в, скажем, 100ричную систему счисления. | |
|
|
|
|
|
|
|
для: Unkind
(25.05.2007 в 22:29)
| | (50 * 2 + 53 * 1)
если 2 - здесь - основание системы счисления, то множить такие коэффициенты вы имеете право лишь на цифры, не превышающие это основание. То есть либо на 0 либо на 1 .
У Вас же код символа в общем случае восьмиразрядный. Хранит значения от 0 до 255.
Значит Вам может подойти система счисления лишь 256-ричная или еще выше. В этом случае число будет таким:
50*256+ 53*1
Вы правда почему-то пытаетесь хранить левые символы в старших разрядах числа а не в младших, но это уже вопрос второй. | |
|
|
|
|
|
|
|
для: Trianon
(25.05.2007 в 22:34)
| | Точно, блин. Жаль. | |
|
|
|