Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.047 c
3-1102061042
pkm
2004-12-03 11:04
2005.01.02
Не по теме, но на другие темы форума не могу зайти: ошбка!!!


14-1102941844
IllusoryOrion
2004-12-13 15:44
2005.01.02
Что бы вы хотели видеть в...


14-1102531328
begin...end
2004-12-08 21:42
2005.01.02
Выбор монитора


3-1102067999
alehan
2004-12-03 12:59
2005.01.02
Кластерный индекс


1-1103151212
OnEvent
2004-12-16 01:53
2005.01.02
Как в своём компоненте скрыть свойства доставшиеся от родителя





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский