Форум: "Основная";
Текущий архив: 2005.01.02;
Скачать: [xml.tar.bz2];
ВнизПомогитес двоичным числом разобраться Найти похожие ветки
← →
Kolan © (2004-12-11 16:14) [0]Здравствуйте,
Задеча:
Есть 28 разрядное двоичное число. Это число задает 4 байта. Прервый 00llllll второй llllllll третий 00hhhhhh четвертый hhhhhhhh. Как из этого числа эти байты вычеслить. Формула?
Если не понятно то например(два байта):Hbits := Value div 4;
if Hbits < 1 then
Hbits := 1;
Lbits := Value - Hbits * 4;
Value это десятичное число. В итоге имею 2 байта.
← →
uny © (2004-12-11 16:35) [1]взять калькулятор - в виндовсе, переключить его в битовый режим и забить нужный байт единицами.
т.е. если нужен нулевой байт , то забить 8 единиц
если нужен первый, то 1111111100000000
вот, переключить калькулятор в десятичный вид и прочитать число.
а в своей проге написать
нужный байт:=(число содержащее все 4 байта) and (полученное в калькуляторе число);
← →
uny © (2004-12-11 16:39) [2][1] забыл - если байт не нулевой, то нужно так или иначе сдвинуть к нулевой позиции. т.е. по формуле получили число для первого(не нулевого) байта - нужно это число разделить на 2 в степени 8
← →
GanibalLector © (2004-12-11 16:52) [3]> hhhhhhhh
Это как понять? В двоичной системе либо "0" либо "1".А то ШО?
← →
begin...end © (2004-12-11 17:15) [4]> Kolan © (11.12.04 16:14)
> Есть 28 разрядное двоичное число. Это число задает 4 байта.
Это как?
← →
uny © (2004-12-11 17:22) [5][4] наверно из 32 4 не используются:)))
← →
begin...end © (2004-12-11 18:19) [6]> Kolan © (11.12.04 16:14)
Что-то Вы молчите, так что буду разговаривать сам с собой.
Есть очень простой способ решения:var
Parts: array [0..3] of Byte;
Value: Cardinal absolute Parts;
begin
// Присваиваем значение переменной Value
// Работаем с каждым её байтом в отдельности как с элементом массива Parts
end.
> Если не понятно то например(два байта):
> Hbits := Value div 4;
> if Hbits < 1 then
> Hbits := 1;
> Lbits := Value - Hbits * 4;
> Value это десятичное число. В итоге имею 2 байта.
А здесь можно было, кроме способа, описанного выше, использовать стандартные функции Lo и Hi, т.к. байта всего 2.
Ну и, наконец, можно с помощью сдвигов и масок.
← →
cyborg © (2004-12-11 19:07) [7]Что-то типа этого?
Function GetBit(Var bytes : cardinal; num : byte) : cardinal;
begin
Result:=(bytes shr (num-1)) and 1;
end;
bytes - твои биты в 32 битовом числе, num - номер бита справа.
возвращает 1 или 0;
← →
begin...end © (2004-12-11 19:22) [8]> [7] cyborg © (11.12.04 19:07)
Ну, во-первых, ему, насколько я понял, нужны не биты, а байты.
А во-вторых, непонятно, зачем использовать для хранения значения 1 бита целых 4 байта.
← →
uny © (2004-12-11 19:52) [9]...а кто по площадям...
← →
begin...end © (2004-12-11 20:19) [10]> [9] uny © (11.12.04 19:52)
Что-что?
← →
cyborg © (2004-12-12 12:43) [11]
> непонятно, зачем использовать для хранения значения 1 бита
> целых 4 байта.
Чтобы в 32 битный регистр значение помещалось, так, как процессоры 32 битные сейчас в основном. Что, зажал 3 байта? :)
← →
Kolan © (2004-12-13 12:06) [12]
> Это как понять? В двоичной системе либо "0" либо "1".А то
> ШО?
h и l имеется в виду 0 или 1.
> uny © (11.12.04 17:22) [5]
> [4] наверно из 32 4 не используются:)))
Да не используются.
> > Kolan © (11.12.04 16:14)
>
> Что-то Вы молчите, так что буду разговаривать сам с собой.
Извените нет на работе "гонит" не мог ответить.
А я вот так извратился :)procedure TKFreGrafCommands.EvalFourBytsFromValue(Value: LongInt);
var
HHiByte, LHiByte, HlowByte, LLowByte: Integer;
BothLowBytes, BothHiBytes: Integer;
begin
HHiByte := 0;
LHiByte := 0;
HlowByte:= 0;
LLowByte := 0;
BothLowBytes:= 0;
BothHiBytes:= 0;
if Value > 16383 then
begin
BothLowBytes := Value - 16384 * (Value div 16384);
BothHiBytes := Value div 16384;
end
else
begin
BothLowBytes := Value;
BothHiBytes := 0;
end;
if BothLowBytes > 255 then
begin
LLowByte := BothLowBytes - 256 * (BothLowBytes div 256);
HlowByte := BothLowBytes div 256;
end
else
begin
LLowByte := BothLowBytes;
HlowByte := 0;
end;
if BothHiBytes > 255 then
begin
LHiByte := BothHiBytes - 256 * (BothHiBytes div 256);
HHiByte := BothHiBytes div 256;
end
else
begin
LHiByte := BothHiBytes;
HHiByte := 0;
end;
end;
> var
> Parts: array [0..3] of Byte;
> Value: Cardinal absolute Parts;
>
> begin
> // Присваиваем значение переменной Value
> // Работаем с каждым её байтом в отдельности как с элементом
> массива Parts
> end.
Не очень понял. Как сделать.
← →
begin...end © (2004-12-13 13:04) [13]> [12] Kolan © (13.12.04 12:06)
> Не очень понял. Как сделать.
Идея решения в [6] состоит в том, что массив из четырёх байт (Parts) располагается в памяти по тому же адресу, что и четырёхбайтная переменная Value. Такое размещение достигается применением директивы absolute. Т.е. первый байт переменной Value "совмещён" с первым байтом массива Parts. А поскольку это array of Byte, т.е. каждый элемент массива занимает 1 байт, то, обратившись к первому элементу массива, мы получаем первый байт переменной Value. Другими словами, одну и ту же область памяти можно рассматривать и как место размещения числа Value, и как массив из четырёх байт Parts.
Присвоив переменной Value какое-либо значение, мы размещаем это значение в четырёх байтах памяти. А потом, обращаясь к первому, второму и т.д. элементам массива, получаем первый, второй и т.д. байты числа Value.
Если Вам эти байты нужны в виде отдельных переменных, пожалуйста - присвойте нужным переменным значения соответствующих элементов массива, и всё.
Например, есть у Вас число 4000000000 (в десятичной системе).
В двоичной оно запишется так: 11101110 01101011 00101000 00000000.
Таким образом, в первом байте (справа) находится число 0, во втором - 40, в третьем - 107, и в четвёртом - 238.
Теперь выполните такой код:var
I: Byte;
Parts: array [0..3] of Byte;
Value: Cardinal absolute Parts;
begin
// Присваиваем значение переменной Value
Value := 4000000000;
// Работаем с каждым её байтом в отдельности как с элементом массива Parts
for I := Low(Parts) to High(Parts) do
ShowMessage(IntToStr(Parts[I]))
end
и сравните показанные числа с числами, приведёнными выше (0; 40; 107; 238).
Думаю, теперь понятно.
← →
Kolan © (2004-12-13 13:21) [14]
> begin...end © (13.12.04 13:04) [13]
Благодарю за ответ.
> что массив из четырёх байт (Parts) располагается в памяти
> по тому же адресу
В жизни бы не догадался.
:)
← →
Kolan © (2004-12-14 16:05) [15]
> begin...end © (13.12.04 13:04) [13]
Хороший способ, но ты забыл что число то 28 разрядное. Поэтому
0 0 63 255 + 0 0 0 1 будет не 0 0 64 0 , а 0 1 0 0
← →
Digitman © (2004-12-14 16:20) [16]
> Поэтому
> 0 0 63 255 + 0 0 0 1 будет не 0 0 64 0 , а 0 1 0 0
галиматья какая-то ...
если диапазон представления числа в дв.виде ограничен 28-ю разрядами , то
0 0 63 255 + 0 0 0 1 будет именно 0 0 64 0 , а не 0 1 0 0
← →
Kolan © (2004-12-14 21:51) [17]
> Digitman © (14.12.04 16:20) [16]
Благодарю мой алгоритм работает.
Это не галимотья а прикол микросхемы. Я точно не разбирался, но число там 28 разрядное и
записывается так
xxbbbbbb bbbbbbbb xxbbbbbb bbbbbbbb где xx не используются, а b это "0" или "1"
Поэтому верно.
0 0 63 255 + 0 0 0 1 будет не 0 0 64 0 , а 0 1 0 0
Пользователь моей программы видит только десятичное число. А я его сам преобразую.
Еще раз благодарю за помощь.
Интересно бы как нибкдь поизяшнее такой алгоритм сделать.
← →
Digitman © (2004-12-15 08:11) [18]т.е., как я понял, тебе просто нужно некое заданное тобой 28-разр. число представить в указанном формате ?
← →
begin...end © (2004-12-15 18:53) [19]> [17] Kolan © (14.12.04 21:51)
> Это не галимотья а прикол микросхемы. Я точно не разбирался,
> но число там 28 разрядное и
> записывается так
> xxbbbbbb bbbbbbbb xxbbbbbb bbbbbbbb где xx не используются,
> а b это "0" или "1"
Ну а в программе-то Вашей это число в каком формате представлено?
Два старших бита из второго и третьего байтов не используются, что ли (т.е. на них можно не обращать внимание)?
Если так, то думаю, что можно всё же воспользоваться и предложенным мной способом, только немного модифицировать значения первого и третьего элементов массива, а именно применить к ним "and 00111111", т.е. and $3F. Тогда эти 2 старших бита просто обнулятся.
В общем, хотелось бы побольше подробностей.
← →
uny © (2004-12-15 19:58) [20]я будто что то упустил - в чём проблема?
← →
DesWind © (2004-12-15 21:00) [21]
Насколько я понял надо преобразовать двойное слово какого-то микроконтроллера в слово для Intel;
function MC_DWORD_To_Intel_WORD(MC_DWORD: integer): integer;
var
MCValue : array[0..1] of word;
IntValue: cardinal absolute MCValue;
begin
MCValue:=MC_DWORD;
MCValue[0]:=MCValue shl 2;
Result:=(IntValue shr 2)and $0HHHHHHH
end;
Это в том случае если MC_DWORD представлено ввиде xxbbbbbb bbbbbbbb xxbbbbbb bbbbbbbb
← →
DesWind © (2004-12-15 21:01) [22]
Насколько я понял надо преобразовать двойное слово какого-то микроконтроллера в слово для Intel;
function MC_DWORD_To_Intel_WORD(MC_DWORD: integer): integer;
var
MCValue : array[0..1] of word;
IntValue: cardinal absolute MCValue;
begin
MCValue:=MC_DWORD;
MCValue[0]:=MCValue shl 2;
Result:=(IntValue shr 2)and $0HHHHHHH
end;
Это в том случае если MC_DWORD представлено ввиде xxbbbbbb bbbbbbbb xxbbbbbb bbbbbbbb
← →
DesWind © (2004-12-15 21:11) [23]Прошу прощения. Так будет лучше:
function MC_DWORD_To_Intel_WORD(MC_DWORD: cardinal): cardinal;
Если двойное слово микроконтроллера со знаком, то его старший бит надо перенести в старший бит интеловского слова;
← →
Kolan © (2004-12-16 03:10) [24]
> begin...end © (15.12.04 18:53) [19]
Вот подробности.
Есть прибор там макросхема. Пользователь задает частоту. Потом по данной мне ф-ле я ее привожу к другому числу. Далее посылаю устройству.А мокросхема, Забыл у точнить, завтра точно сформулирую, в устройстве хочет чтоб я ей передал именно 28 разрадов вот так и не как иначе.
xxbbbbbb bbbbbbbb xxbbbbbb bbbbbbbb
> DesWind © (15.12.04 21:01) [22]
>
> Насколько я понял надо преобразовать двойное слово какого-то
> микроконтроллера в слово для Intel;
Наоборот мне из компьютера на контроллер слать надо. Мой алгоритм
> Kolan © (13.12.04 12:06) [12]
хорошо работает (Только чуть я шас поправил где надо 255 на 256 итд.
>begin...end © (15.12.04 18:53) [19]
Попробую
Благодарю за ответы. :)
← →
Sha © (2004-12-16 09:52) [25]ToIntel
y:=(x shr 2) and $0FFFC000 or x and $3FFF
FromIntelx:=(y shl 2) and $3FFF0000 or y and $3FFF
← →
Ega23 © (2004-12-16 10:01) [26]shl, shr ?
← →
Sha © (2004-12-16 10:09) [27]Sha © (16.12.04 09:52) [25]
Не учел, что внутри слов байты тоже переставлены.
Тогда такvar x, y: cardinal;
ToIntelу:=(x shr 8) and $00FF00FF or (x shl 8) and $FF00FF00;
y:=(y shr 2) and $0FFFC000 or y and $3FFF;
FromIntelx:=(y shr 8) and $00FF00FF or (y shl 8) and $FF00FF00;
x:=(x shl 2) and $3FFF0000 or x and $3FFF;
← →
Ega23 © (2004-12-16 10:30) [28]
function TTIFF.Swap32(Value: Integer): Integer;
var
b1, b2, b3, b4 : Integer;
begin
b1 := Value and 255;
b2 := (Value shr 8) and 255;
b3 := (Value shr 16) and 255;
b4 := (Value shr 24) and 255;
b1 := b1 shl 24;
b2 := b2 shl 16;
b3 := b3 shl 8;
Result := b1 or b2 or b3 or b4;
end;
← →
DesWind © (2004-12-16 11:16) [29]
function Intel_WORD_To_MC_DWORD(Intel_WORD: cardinal): cardinal;
var
MCValue : array[0..1] of word;
IntValue: cardinal absolute MCValue;
begin
IntValue:=Intel_WORD;
MCValue[1]:=MCValue[1] shl 2;
MCValue[1]:=MCValue[1] or ((MCValue[0] and $C000) shr 14)
Result:=IntValue;
end;
← →
begin...end © (2004-12-16 19:46) [30]> [24] Kolan © (16.12.04 03:10)
> Наоборот мне из компьютера на контроллер слать надо.
Ну так бы сразу и сказали... В таком случае [19] даже и пробовать не нужно - не поможет, т.к. значения нескольких битов просто потеряются.
Сейчас попытаюсь сформулировать задание так, как я его понял, и описать решение.
Имеется число (пусть это будет Cardinal). В памяти эта переменная занимает 4 байта, однако число умещается в младших 28 битах. Оставшиеся 4 старших бита всегда равны 0. Требуется представить это число в таком виде:xxbbbbbb bbbbbbbb xxaaaaaa aaaaaaaa
,
где все символы a и b - это и есть те 28 битов, которые были "задействованы" для представления исходного числа.
Т.е., если считать биты, начиная с нуля (справа), то 13-й бит этого преобразованного числа - это 13-й бит исходного, а вот 16-му биту нового числа соответствует 14-й бит старого.
Значения 14, 15, 30 и 31-го битов преобразованного числа игнорируются (обозначены как x).
Тогда последовательность преобразований может быть такой:
I - исходное число:xxxxbbbbbbbbbbbbbbaaaaaaaaaaaaaa
.
1. В исходном числе обнуляем младшие 14 битов, применяя and $FFFFC000, в результате получаем:xxxxbbbbbbbbbbbbbb00000000000000
.
2. Сдвигаем полученное число влево на 2 разряда (shl 2), получаем:xxbbbbbbbbbbbbbb0000000000000000
<- назовём это J.
3. В исходном числе I обнуляем старшие 18 битов, применяя and $3FFF, в результате получаем:000000000000000000aaaaaaaaaaaaaa
<- назовём это K.
4. Объединяем J и K (операция or), получается:xxbbbbbbbbbbbbbb00aaaaaaaaaaaaaa
.
Это-то нам и нужно, выделенные 2 нолика находятся в 14-м и 15-м битах, которые игнорируются. Биты исходного числа расположены до и после этих ноликов.
Теперь всё это объединим:Y := ((X and $FFFFC000) shl 2) or (X and $3FFF)
.
(Скобки здесь нужны не все, они оставлены для наглядности.)
Это решение полностью аналогично решению [25] Sha © (16.12.04 09:52) (FromIntel), только там число вначале сдвигается на 2 разряда влево, а потом обнуляются младшие 16 битов (результат будет такой же, как и после пунктов 1 и 2). Я просто попробовал пояснить.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.01.02;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.047 c