Подскажите как выделить байт из двоичного числа

Тема в разделе "Delphi - FAQ", создана пользователем florion, 24 фев 2009.

  1. florion

    florion Гость

    Люди помогите, очень нужно решить такую задачу. В Delphi особо не шарю, но думаю что код будет сосотять всего из нескольких строчек.

    На форме присутствют 2 Edit и 1 Button, в первый Edit нужно ввести десятичное число, а во втором получить десятичный результат выполнения программы при нажатии на кнопку. Программа заключается в том, чтобы выделить к примеру 3-ий байт из десятичного числа переведенного в 2 сс и найти его десятичный эквивалент.

    Пример: Имеется число в десятичной сс 2550550550
    следовательно в двоичной 10011000.00000110.01010000.00010110 (байты отделены точками, считаются с право налево)
    т.е. 3-им байтом является 00000110 => в 10 сс это чилсло 6.
     
  2. etc

    etc Гость

    Сдвигами наверное надо тут.
     
  3. Poseidon

    Poseidon Гость

    Вот те пример для второго байта.

    Код (Text):
    procedure TForm1.Button1Click(Sender: TObject);
    var n1, n2: integer;
    begin
    n1 := StrToInt(Edit1.Text);
    n2 := n1 xor $0000FF00;
    Edit2.Text := IntToStr(n2);
    end;
     
  4. etc

    etc Гость

    Ай молодец. :)
     
  5. Kmet

    Kmet Well-Known Member

    Регистрация:
    25 май 2006
    Сообщения:
    1.017
    Симпатии:
    1
    Poseidon почему xor?! :)
     
  6. interrupt

    interrupt Гость

    Poseidon, что-то не то!

    Вот пример:
    (ищем третий байт)
    10011000.00000110.01010000.00010110
    xor
    00000000.11111111.00000000.00000000
    =
    10011000.11111001.01010000.00010110


    Надо использовать And:
    10011000.00000110.01010000.00010110
    and
    00000000.11111111.00000000.00000000
    =
    00000000.00000110.00000000.00000000

    Тогда мы получим число с выделенным нужным байтом (остальные будут нули).
    Далее сдвигаем на (номер байта-1) туда -> вправо т.е., это операция SHR вроде в Дельфях.
    В данном случае сдвиг на 2:
    00000000.00000000.00000000.00000110
    Вот собственно и результат.
    Искомое число 6.
     
  7. florion

    florion Гость

    Помогли написать вот такую вот програмулину.
    Состоит из нескольких частей:
    1. В Edit1 вводится десятичное число от 2*10 ^9 до 3*10 ^9, при на жании на Button 1 происходят такие действия: в Edit2 появляется введенное 10-ое число только в 2сс, в Edit3 выделяется 3-ий байт двоичного числа, в Edit4 выделенный 3-ий байт переводится в 10сс.

    2.После нажатия Button2 в Edit5 появляется введенное в Edit1 10-ое число только в 2сс, в Edit6 отображается 10 число выполнения операции выделения 3-его байта из Edit5 и замены им 2 и 1 байта

    Как подругому можно наисать эту програмку. И как втавить ассемблерную вставку в этот код.

    unit Unit1;

    interface

    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls, Math;

    type
    TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    Edit3: TEdit;
    Button2: TButton;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    private
    function IntToBin(dec: int64): string; //Функция перевода десятичного числа в двоичное
    function BinToInt(Value: string): int64; //функция перевода двоичного в десятичное


    { Private declarations }
    public
    { Public declarations }
    end;

    var
    Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.Button1Click(Sender: TObject);
    var
    str:string;
    begin
    str:=IntToBin(strtoint64(Edit1.Text)); //перевод десятичного числа в двоичное с помощью самописной функции IntToBin
    Edit2.Text:=str; //Отображение двоичного числа в Edit2
    Edit3.Text:=Copy(str,9,8); //3-й байт двоичного числа
    Edit4.Text:= inttostr(BinToInt(Edit3.Text)); //перевод 3-го байта в десятичное
    end;
    {--------------------------------------------------------------------------------}
    function TForm1.IntToBin(Dec: int64): string; //Собственно и есть самописная функция перевода десятичного числа в двоичное
    var
    del: int64;
    size: Integer;
    str:string;
    begin
    Result:='';
    str:='';
    del:=dec;
    While (del div 2)<>0 do
    begin
    str:=str+inttostr(del mod 2);
    del:=(del div 2);
    end;
    str:=str+'1';
    size:=Length(str);
    while size>0 do
    begin
    Result:=Result+copy(str,size,1);
    size:=size-1;
    end;

    end;
    {--------------------------------------------------------------------------------}
    function TForm1.BinToInt(Value: String): int64 ; //Собственно и есть самописная функция перевода двоичного числа в десятичное
    var
    i:integer;
    begin
    i:=1;
    Result:=0;
    while not(i>Length(Value)) do
    begin
    if copy(Value,i,1)='1' then Result:=Result+strtoint64(Floattostr(IntPower(2,(Length(Value))-i))) ;
    i:=i+1;
    end;
    end;
    {--------------------------------------------------------------------------------}
    procedure TForm1.Button2Click(Sender: TObject);
    var
    str:string;
    begin
    str:=IntToBin(strtoint64(Edit1.Text)); //перевод десятичного числа в двоичное с помощью самописной функции IntToBin
    Edit5.Text:=Copy(str,1,8)+Copy(str,9,8)+Copy(str,9,8)+Copy(str,9,8); //Замена в исходном числе 2 и 1 байты 3им и перевести полученное число в 10 сс
    Edit6.Text:= inttostr(BinToInt(Edit5.Text)); //перевод в десятичное
    end;

    end.
     
  8. interrupt

    interrupt Гость

    Простите, но это БРЕД!
    Для выполнения простейшей операции использовать сложные (в машинном понимании) операции преобразования числе в строки и далее обратно, + в дельфи операции со строками медленные вообще.
    Есть функции
    HiWord()
    LoWord()
    HiByte()
    LoByte()
    для извлечения старших слов\байтов.
    Соотвественно если число long (4б), то например вытащить 3 байт будет: LoByte(HiWord(X))

    Кроме того, вот написал функцию, выделяющая n-ый байт из числа:

    Код (Text):
    function get_n_byte(x: longint; number: byte): byte;
    begin

    get_n_byte := ( x shl ( 8 * ( sizeof( longint ) - number ))) shr ( 8 * ( sizeof( longint ) - 1 ));

    end;


    пример
    вход: 1047468688, ищем 1 байт
    выход: 144

    1047468688 = 00111110 01101111 00011010 10010000 b
    10010000 b = 144.
    При поиске 2 байта выдаст соответственно 26 (11010)
    3 - 111 (1101111),
    4 - 62 (111110).

    И в догонку, может кому-то понадобиться, вытаскивание бита по номеру:
    Код (Text):
    function get_n_bit(x: longint; number: byte): byte;
    begin

    get_n_bit :=(x shl (8*sizeof(longint)-number)) shr (8*sizeof(longint)-1);


    end;
    И более элегантный метод получения n-ого бита:
    Код (Text):
    function get_n_bit(x: longint; number: byte): byte;
    begin

    get_n_bit := byte(((1 shl number) AND x) <> 0);

    end;
     
  9. etc

    etc Гость

    ... превращаются ..... в элегантные шорты :)
     
Загрузка...
Похожие Темы - Подскажите как выделить
  1. kuklofon
    Ответов:
    1
    Просмотров:
    80
  2. Sevas
    Ответов:
    1
    Просмотров:
    1.214
  3. Gandliar
    Ответов:
    3
    Просмотров:
    1.619
  4. iNet
    Ответов:
    3
    Просмотров:
    2.184
  5. Amfion
    Ответов:
    2
    Просмотров:
    1.751

Поделиться этой страницей