Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> вывести integer в виде массива бит 
:(
    Опции темы
СЭНСЭЙ
Дата 6.4.2009, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 432
Регистрация: 20.3.2006

Репутация: нет
Всего: нет



Привет всем.
Подскажите как попроще вывести значение integer (к примеру) в виде массива бит
PM MAIL   Вверх
CodeMonkey
Дата 6.4.2009, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Я бы сделал как-то так (писал на коленке, могут быть ошибки):
Код
function ByteToBinStr(const B: Byte): String; // байт в строку битов
const
  C: array[0..15] of String = ('0000', '0001', '0010', '0011',
                                             '0100', '0101', '0110', '0111',
                                             '1000', '1001', '1010', '1011',
                                             '1100', '1101', '1110', '1111');
begin
  Result := C[B shr 4] + C [B and $F];
end;

function IntToBitStr(const I: Integer): String; // Integer в строку битов
begin
   Result := ByteToBinStr(I shr 24) + 
                  ByteToBinStr(I shr 16) + 
                  ByteToBinStr(I shr 8)
                  ByteToBinStr(I);
end;



--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
СЭНСЭЙ
Дата 6.4.2009, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 432
Регистрация: 20.3.2006

Репутация: нет
Всего: нет



Хм.. Очень интересно и красиво!!!
А попроще никак?
PM MAIL   Вверх
CodeMonkey
Дата 6.4.2009, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Попроще - это как? Типа, чтоб препод сразу понял, что сами писали? smile 


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
MetalFan
Дата 6.4.2009, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



накидал на коленке "по проще".
Код

function BufToBit( ABuf: Integer ): string;
var
  i: Integer;
begin
  SetLength(Result, 36 );
  for i := SizeOf(ABuf)*8 downto 1 do
  begin
    if (ABuf and $1)=1 then
      Result[i] := '1'
    else
      Result[i] := '0';
    ABuf := ABuf shr 1;
  end;
end;

ABuf можно обозначить любым простым типом.
з.ы. но в коде есть ошибка smile найдешь - молодец

Это сообщение отредактировал(а) MetalFan - 6.4.2009, 11:28


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Андре
Дата 6.4.2009, 14:09 (ссылка) |  (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 23.3.2009

Репутация: нет
Всего: нет



Берем готовую функцию IntToHex и модернизируем немножко.
Код

procedure CvtInt; 
{ IN:
    EAX:  The integer value to be converted to text
    ESI:  Ptr to the right-hand side of the output buffer:  LEA ESI, StrBuf[16]
    ECX:  Base for conversion: 0 for signed decimal, 10 or 16 for unsigned
    EDX:  Precision: zero padded minimum field width
  OUT:
    ESI:  Ptr to start of converted text (not start of buffer)
    ECX:  Length of converted text
}
asm
        OR      CL,CL
        JNZ     @CvtLoop
@C1:    OR      EAX,EAX
        JNS     @C2
        NEG     EAX
        CALL    @C2
        MOV     AL,'-'
        INC     ECX
        DEC     ESI
        MOV     [ESI],AL
        RET
@C2:    MOV     ECX,10

@CvtLoop:
        PUSH    EDX
        PUSH    ESI
@D1:    XOR     EDX,EDX
        DIV     ECX
        DEC     ESI
        ADD     DL,'0'
        CMP     DL,'0'+10
        JB      @D2
        ADD     DL,('A'-'0')-10
@D2:    MOV     [ESI],DL
        OR      EAX,EAX
        JNE     @D1
        POP     ECX
        POP     EDX
        SUB     ECX,ESI
        SUB     EDX,ECX
        JBE     @D5
        ADD     ECX,EDX
        MOV     AL,'0'
        SUB     ESI,EDX
        JMP     @z
@zloop: MOV     [ESI+EDX],AL
@z:     DEC     EDX
        JNZ     @zloop
        MOV     [ESI],AL
@D5:
end;

function IntToAny(Value: Integer; Digits: Integer): string;
//  FmtStr(Result, '%.*x', [Digits, Value]);
asm
        CMP     EDX, 32        // Digits < buffer length?
        JBE     @A1
        XOR     EDX, EDX
@A1:    PUSH    ESI
        MOV     ESI, ESP
        SUB     ESP, 32
        PUSH    ECX            // result ptr
        MOV     ECX, 2        // ну а тут нужную нам систему счисления :)
        CALL    CvtInt
        MOV     EDX, ESI
        POP     EAX            // result ptr
        CALL    System.@LStrFromPCharLen
        ADD     ESP, 32
        POP     ESI
end;

PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 6.4.2009, 14:23 (ссылка) |  (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 1
Всего: 250



Цитата(Андре @  6.4.2009,  13:09 Найти цитируемый пост)
Берем готовую функцию IntToHex и модернизируем немножко.

нда.. форум то по паскалю, а не по асму. И вобще в чем смысл то, делать непереносимым решение для задачи, не требущей критической оптимизации ?!



--------------------
PM MAIL WWW   Вверх
marinovsoft
Дата 6.4.2009, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 25.1.2009
Где: Кемерово

Репутация: нет
Всего: нет



Вот, писал на коленках:
Код

function byte2bit(b:byte):String;
var i:byte;
    tmpStr:String;
const bit_arr:array[1..8] of byte=($1,$2,$4,$8,$10,$20,$40,$80);

begin
   tmpStr:='';
   for i:=1 to 8 do
   if (b and bit_arr[i])=bit_arr[i] then
      tmpStr:='1'+tmpStr
   else tmpStr:='0'+tmpStr;
   byte2bit:=tmpStr;
end;


А это из работающей программы скопировано 

Код

Const
      Arr1:Array[1..8] of byte=($1,$2,$4,$8,$10,$20,$40,$80);
Procedure Write_Byte(B:Byte);
Var
  i:Byte;
begin
     Write_bit_0;  { startovi bit }
     For i:=1 to 8 do
      If (B And Arr1[i])=Arr1[i] then
         Write_bit_1
      else
         Write_bit_0;
     Write_bit_1;  { 1st stopovi bit }
     Write_bit_1;  { 2nd stopovi bit }
end;


Сама работающая программа здесь _http://marinovsoft.narod.ru/korvet/msxcas.rar
PM MAIL WWW ICQ   Вверх
MetalFan
  Дата 6.4.2009, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



имхо у миня лучче всех получилось) smile  smile 


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
CodeMonkey
Дата 6.4.2009, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(MetalFan @  6.4.2009,  15:37 Найти цитируемый пост)
имхо у миня лучче всех получилось)    

Я так думаю, что каждому свой вариант нравится лучше остальных ;)


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
mes
Дата 6.4.2009, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 1
Всего: 250



Цитата(MetalFan @  6.4.2009,  14:37 Найти цитируемый пост)
имхо у миня лучче всех получилось) smile  smile 

 но откуда взялось 36 ?!  smile 
Цитата(MetalFan @  6.4.2009,  10:27 Найти цитируемый пост)
 SetLength(Result, 36 );




Это сообщение отредактировал(а) mes - 6.4.2009, 15:57


--------------------
PM MAIL WWW   Вверх
CodeMonkey
Дата 6.4.2009, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(mes @  6.4.2009,  15:56 Найти цитируемый пост)
 но откуда взялось 36 ?! ;)

А вдруг чо! О_О  smile 


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Akella
Дата 6.4.2009, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 36
Всего: 329



Цитата(mes @  6.4.2009,  15:56 Найти цитируемый пост)
но откуда взялось 36 ?!  smile 

Как это откуда? Со справочника Стэля.
PM MAIL   Вверх
MetalFan
Дата 6.4.2009, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(Akella @  6.4.2009,  16:02 Найти цитируемый пост)
Как это откуда? Со справочника Стэля. 

хтоето???  smile 
а взялось из SizeOf( Integer ) * 8


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
mopsa
Дата 6.4.2009, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 11.1.2009
Где: Екатеринбург/Асбе ст

Репутация: нет
Всего: 1



Цитата(MetalFan @ 6.4.2009,  19:27)
а взялось из SizeOf( Integer ) * 8

но это будет 32
но метод MetalFan`a после небольшой поправки мне кажется лучьшим
PM MAIL   Вверх
MetalFan
Дата 6.4.2009, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(mopsa @  6.4.2009,  16:44 Найти цитируемый пост)
но это будет 32
но метод MetalFan`a после небольшой поправки мне кажется лучьшим 

а, ну таки тогда две ошибки было) плохо арифметику в школе учил, поэтому вышло 8*4=36)

Это сообщение отредактировал(а) MetalFan - 6.4.2009, 16:49


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
CodeMonkey
Дата 6.4.2009, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Вот ещё до кучи вариант моего варианта - стал пострашнее, но зато работает в два раза быстрее MetalFan-ского. Правда, если заменить копирование в Dst на Move (для варианта со String в D2009), то прирост скорости будет всего около 25-ти процентов. 

Код
// ANSI:
function RawToBitStr(const Data; const Size: Integer): AnsiString;
const
  C: array[0..15] of AnsiString = ('0000', '0001', '0010', '0011',
                                   '0100', '0101', '0110', '0111',
                                   '1000', '1001', '1010', '1011',
                                   '1100', '1101', '1110', '1111');
var
  X: Integer;
  Src: PByte;
  Dst: PInteger;
begin
  SetLength(Result, Size * 8);

  Src := Pointer(Integer(@Data) + Size - 1);
  Dst := Pointer(Result);

  for X := 0 to Size - 1 do
  begin
    Dst^ := PInteger(C[Src^ shr 4])^;
    Inc(Dst);
    Dst^ := PInteger(C[Src^ and $F])^;
    Inc(Dst);
    Dec(Src);
  end;
end;

// Универсальный:
function RawToBitStr(const Data; const Size: Integer): String;
const
  C: array[0..15] of String = ('0000', '0001', '0010', '0011',
                               '0100', '0101', '0110', '0111',
                               '1000', '1001', '1010', '1011',
                               '1100', '1101', '1110', '1111');
var
  X: Integer;
  Src: PByte;
  Dst: PChar;
begin
  SetLength(Result, Size * 8);

  Src := Pointer(Integer(@Data) + Size - 1);
  Dst := Pointer(Result);

  for X := 0 to Size - 1 do
  begin
    Move(PInteger(C[Src^ shr 4])^, Dst^, 4 * SizeOf(Char));
    Inc(Dst, 4);
    Move(PInteger(C[Src^ and $F])^, Dst^, 4 * SizeOf(Char));
    Inc(Dst, 4);
    Dec(Src);
  end;
end;

function IntToBitStr(const I: Integer): AnsiString; inline;
begin
  Result := RawToBitStr(I, SizeOf(I));
end;


А реализация через CvtInt работает в 2.5 раза медленнее MetalFan-ской - но зато она проще всего в реализации (всего-то и надо, как цифирьку 16 в IntToHex поменять на 2-ку).


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
MetalFan
Дата 6.4.2009, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(CodeMonkey @  6.4.2009,  17:50 Найти цитируемый пост)
зато работает в два раза быстрее MetalFan-ского

ну конееечно! хитрый! сразу 4 символа в один заход пишешь...  а если таблицу расширить до полного байта, то еще быстрее дело пойдет ;)
зы. зато мой вариант нагляднее и понятнее) и преподу его проще объяснить ;) имхо


Это сообщение отредактировал(а) MetalFan - 6.4.2009, 18:22


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
CodeMonkey
Дата 6.4.2009, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(MetalFan @  6.4.2009,  18:17 Найти цитируемый пост)
а если таблицу расширить до полного байта, то еще быстрее дело пойдет ;)

Ага smile) Только таблицу на полный байт замучаешся писать. Да, твой вариант простейший в реализации.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
MetalFan
Дата 6.4.2009, 20:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(CodeMonkey @  6.4.2009,  19:48 Найти цитируемый пост)
Только таблицу на полный байт замучаешся писать.

а ее можно при запуске приложения генерировать)


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Beltar
Дата 7.4.2009, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 3
Всего: 7



Код

Mask:=1;
for i:=0 to SizeOf(IntegerVariable) do
  begin
  if (IntegerVariable and Mask)>0 
    then Вывести 1
    else Вывести 0
  Mask:=Mask shl 1;  
  end;


Или я не прав? smile


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
mes
Дата 7.4.2009, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 1
Всего: 250



Цитата(Beltar @  7.4.2009,  09:36 Найти цитируемый пост)
Или я не прав? smile 

Цитата(Beltar @  7.4.2009,  09:36 Найти цитируемый пост)
SizeOf(IntegerVariable)

SizeOf() возвращает кол-во байт, а не бит  smile 

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

Добавлено через 3 минуты и 32 секунды
Цитата(MetalFan @  6.4.2009,  17:17 Найти цитируемый пост)
а если таблицу расширить до полного байта, то еще быстрее дело пойдет ;)

только тогда PInteger не подойдет  smile , так как для 8 анси-символов занимают 64 бита.



--------------------
PM MAIL WWW   Вверх
CodeMonkey
Дата 7.4.2009, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(mes @  7.4.2009,  12:59 Найти цитируемый пост)
только тогда PInteger не подойдет   , так как для 8 анси-символов занимают 64 бита.

Ну можно ведь и Move использовать. ... и даже вырвать оттуда кусок для копирования 8-16 байт (16-ть - для unicode), чтоб не вызывать функцию в цикле. Но под таблицу надо будет несколько Кб.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
mes
Дата 7.4.2009, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 1
Всего: 250



Цитата(CodeMonkey @  7.4.2009,  12:06 Найти цитируемый пост)
Ну можно ведь и 

можно, но имхо овчинка выделки не стоит, чтоб идти дальше таблицы из 4х байт


--------------------
PM MAIL WWW   Вверх
bems
Дата 7.4.2009, 14:44 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



Цитата(mes @  6.4.2009,  15:56 Найти цитируемый пост)
но откуда взялось 36 ?! 

предлагаю SetLength(Result, 42 );


--------------------
Обижено школьников: 8
PM MAIL   Вверх
MetalFan
Дата 7.4.2009, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



[off]
Цитата(bems @  7.4.2009,  14:44 Найти цитируемый пост)

предлагаю SetLength(Result, 42 ); 

а поччему не 24? ))) может тогда лучше 44? типа как в анекдоте)[/off]


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
bems
Дата 7.4.2009, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



MetalFan, потому что 42

Это сообщение отредактировал(а) bems - 7.4.2009, 17:18


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0822 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.