![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
dec->bin [D7]
Наталья © (2013-01-28 17:31:00)Из dec->hex:
Format('%.0x',[DEC]);
а в двоичную систему через Format можно?
Dennis I. Komarov (2013-02-02 16:18:00) [1]
> а надо бы
Ну да, есть моментик... Но пусть останется, ибо [2]
Sha (2013-02-01 23:59:00) [2]> без IDE, не проверял
а надо бы
Dennis I. Komarov (2013-02-01 23:33:00) [3]
> aka (29.01.13 19:10) [56]
> Бедная Наташа.
Почему бедная?
function DecToBin(AInt: TAnyInt): string;
var
I: TIntX;
begin
Result:=''; I:= TIntX(AInt);
while I > 0 do begin
Result:=Result + IntToStr(I and $1);
I := I shr 1;
end;
if Result = '' then Result :='0';
end;
(без IDE, не проверял)
Sha (2013-01-29 23:12:00) [4]> DVM © (29.01.13 22:52) [64]
> Вызов Move почти ничего не стоит на таких объемах данных.
4 прохода цикла из [60] тоже "почти ничего не стоят", вопрос в том, что будет дешевле?
Какие объемы данных у Натальи, мне не известно.
DVM (2013-01-29 22:52:00) [5]Вызов Move почти ничего не стоит на таких объемах данных.
Sha (2013-01-29 22:29:00) [6]> Игорь Шевченко © (29.01.13 22:19) [62]
Да, это самый простой вариант. Его, в основном использую.
Плюс-минус 15 мсек при общем времени выполнения 3-5 сек не играют большой роли. Например, иногда даже на современных процессорах
зависимость времени от положения кода в ОП до десятков процентов доходит.
Другие способы значительно реже, только когда приходится с кем-то сравнивать скорость.
Игорь Шевченко (2013-01-29 22:19:00) [7]Sha © (29.01.13 22:05) [60]
Саша, а ты как и чем скорость меряешь ? Стандартно по миллиону(арду) циклов и общее время на число циклов или как-то иначе ?
MBo (2013-01-29 22:11:00) [8]>поэтому сначала имеет смысл проверить что-нибудь попроще, например:
Я прикидывал вариант без Move, но не довёл до ума. Вряд ли уже руки дойдут...
Sha (2013-01-29 22:05:00) [9]> MBo
Скорее всего, вызов Move будет стоить весьма недешево,
поэтому сначала имеет смысл проверить что-нибудь попроще, например:
procedure IntToBinBufferInternal(pBuffer: PChar; Value, Len: integer);
begin
repeat;
dec(Len);
pBuffer[Len]:=Chr(Value and 1 + 48);
Value:=Value shr 1;
until Len<=0;
end;
function IntToBinStringSha(Value: Integer; Len: integer = SizeOf(integer) * 8): string;
begin
if Len<=0 then Result:=''
else begin;
if Len>32 then Len:=32;
SetLength(Result, Len);
IntToBinBufferInternal(pointer(Result), Value, Len);
end;
end;
А потом, при желании, можно ускорять таблицами
и двумя (на каждый SizeOfChar) своими заменителями Move.
P.S. Болею я. Грипп, наверно.
Jeer (2013-01-29 21:34:00) [10]
> Реального - нет. А как задание для семинара на первом-втором
> курсе - вполне нормально.
Если нет реальных применений быстрого преобразования, то и задачи такие для студней бессмысленны.
Другое дело, что предложить 7 вариантов функции IntToBin(), отличающихся алгоритмом - это да.
Ega23 (2013-01-29 20:45:00) [11]
> Я до сих пор не могу представить приложение, в котором требуется
> преобразование (быстрое) из двоичного представления в символьное ;)
Реального - нет. А как задание для семинара на первом-втором курсе - вполне нормально.
Игорь Шевченко (2013-01-29 20:41:00) [12]MBo © (29.01.13 18:48) [55]
> P.S. Ненужной фигнёй заниматься гораздо приятнее, чем нужной
> фигнёй ;)
Я до сих пор не могу представить приложение, в котором требуется преобразование (быстрое) из двоичного представления в символьное ;)
aka (2013-01-29 19:10:00) [13]Бедная Наташа.
MBo (2013-01-29 18:48:00) [14]P.S. Ненужной фигнёй заниматься гораздо приятнее, чем нужной фигнёй ;)
MBo (2013-01-29 18:36:00) [15]>Я немного не о том:
Я понял. Но после исправления на PChar слил всё в в одну строку и проверил производительность - не изменилась.
По читабельности массив лучше, конечно.
Игорь Шевченко (2013-01-29 18:28:00) [16]MBo © (29.01.13 18:17) [52]
Я немного не о том:
const
BitsStrings: array [0 .. $F] of PChar =
('0000', '0001', '0010', '0011',
'0100', '0101', '0110', '0111',
'1000', '1001', '1010', '1011',
'1100', '1101', '1110', '1111');
тогда адресную арифметику можно оставить компилятору
MBo (2013-01-29 18:17:00) [17]>Кстати, а зачем array of string, а не array of PChar ?
Привычнее как-то. Это ни на что не влияет
>мне непривычно приведение к типу Pointer
В данном случае - с константами - это безопасно, зато функция приведения типа не вызывается.
А с массивом PChar - действительно, этого не нужно было бы.
Чуть компактнее вариант:
function IntToBinString(AValue: Integer;
BitsToShow: Integer = SizeOf(Integer) * 8): string;
const
BitsString: PChar = '0000000100100011010001010110011110001001101010111100110111101111';
var
pc: PChar;
begin
SetLength(Result, BitsToShow);
pc := @PChar(Result)[0];
while BitsToShow >= 4 do begin
Move(BitsString[(AValue and $F) * 4], pc[BitsToShow - 4], 4 * SizeOf(Char));
AValue := AValue shr 4;
Dec(BitsToShow, 4);
end;
if BitsToShow > 0 then
Move(BitsString[(AValue and $F) * 4 + 4 - BitsToShow], pc[0], BitsToShow * SizeOf(Char));
end;
brother (2013-01-29 18:15:00) [18]> а зачем array of string
имхо, эти константы забивать прощще)
Игорь Шевченко (2013-01-29 18:03:00) [19]MBo © (29.01.13 17:56) [49]
Кстати, а зачем array of string, а не array of PChar ?
мне непривычно приведение к типу Pointer
MBo (2013-01-29 17:56:00) [20]>Сейчас придет Sha и скажет :)
Ага ;)
От всяких UniqueString я избавился, и 56% времени занимает SetLength под результат. Но резервы, наверно, изыскать можно.
P.S. В последней строчке ошибочка вкралась (мне иногда приходится выводить, например, 14 бит)
Move(Pointer(@BitsStrings[AValue and $F][5 - BitsToShow])^, pc[0], BitsToShow * SizeOf(Char));