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

  • Автор темы florion
  • Дата начала
F

florion

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

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

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

Poseidon

Гость
#3
Вот те пример для второго байта.

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

interrupt

Гость
#6
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.
 
F

florion

Гость
#7
Помогли написать вот такую вот програмулину.
Состоит из нескольких частей:
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.
 
I

interrupt

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

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

Код:
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).

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

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

end;