Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.01.02;
Скачать: CL | DM;

Вниз

Помогитес двоичным числом разобраться   Найти похожие ветки 

 
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
FromIntel   x:=(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;

FromIntel  
 x:=(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;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.048 c
1-1103226157
Ильичев С.А.
2004-12-16 22:42
2005.01.02
Раскладка клавиатуры


14-1102770444
БезОбид
2004-12-11 16:07
2005.01.02
Мануал для "автошемы"


4-1100149622
hyper_omsk
2004-11-11 08:07
2005.01.02
com и мобильник


4-1100578173
DelphiN!
2004-11-16 07:09
2005.01.02
Вывод формы, поверх fsStayOnTop формы


1-1103198145
Roadstar
2004-12-16 14:55
2005.01.02
ListView