![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
![]() Накидал модуль, для преобразования чисел между системами счисления с основаниями 2 и 10.
Работает хорошо, но очень медленно... Как можно его оптимизировать? И ещё, если я что-то упустил, поправьте места, где могут возникать ошибки... Код:
unit uDecBinConvert; interface type TBit = 0..1; TDecimal = 0..9; TBitArray = array of TBit; TDecArray = array of TDecimal; function Dec2Bin (dec: string): string; function Bin2Dec (bin: string): string; implementation uses Classes, SysUtils; procedure StrToBinArr(s: string; var bar: TBitArray); function CharToBit (c: char): TBit; begin if c = '0' then Result:=0 else if c = '1' then Result:=1 else raise (Exception.Create('Invalid character: '''+c+'''')); end; var i:integer; begin while (Length(s)>0)and(s[1] in [#10,#13,#32,#9]) do Delete(s,1,1); while (Length(s)>0)and(s[Length(s)] in [#10,#13,#32,#9]) do Delete(s,Length(s),1); SetLength(bar,Length(s)); for i:=1 to Length(s) do bar[Length(s)-i]:=CharToBit(s[i]); end; procedure StrToDecArr(s: string; var bar: TDecArray); function CharToDec (c: char): TDecimal; begin if (c>=#48) and (c<=#58) then Result:=ord(c)-48 else raise (Exception.Create('Invalid character: '''+c+'''')); end; var i:integer; begin while (Length(s)>0)and(s[1] in [#10,#13,#32,#9]) do Delete(s,1,1); while (Length(s)>0)and(s[Length(s)] in [#10,#13,#32,#9]) do Delete(s,Length(s),1); SetLength(bar,Length(s)); for i:=1 to Length(s) do bar[Length(s)-i]:=CharToDec(s[i]); end; procedure DecArrToStr(dar: TDecArray; var s: string); function DecToChar (d: TDecimal): char; begin Result:=chr(48+d); end; var i:integer; begin s:=''; for i:=1 to Length(dar) do s:=s+DecToChar(dar[Length(dar)-i]); end; procedure BinArrToStr(bar: TBitArray; var s: string); function BinToChar (d: TBit): char; begin Result:=chr(48+d); end; var i:integer; begin s:=''; for i:=1 to Length(bar) do s:=s+BinToChar(bar[Length(bar)-i]); end; procedure IncDecimal(var d: TDecArray); var flag: boolean; index: integer; begin flag:=false; index:=0; while not flag do begin if Length(d)<index+1 then begin SetLength(d,Length(d)+1); d[index]:=0; end; if d[index]=9 then begin d[index]:=0; inc(index) end else begin inc(d[index]); flag:=true; end; end; end; procedure DecDecimal(var d: TDecArray); var flag: boolean; index: integer; begin flag:=false; index:=0; while not flag do begin if d[index]=0 then begin d[index]:=9; inc(index) end else begin dec(d[index]); flag:=true; end; end; while (Length(d)>0)and(d[Length(d)-1]=0) do SetLength(d,Length(d)-1); end; procedure IncBinary(var b: TBitArray); var flag: boolean; index: integer; begin flag:=false; index:=0; while not flag do begin if Length(b)<index+1 then begin SetLength(b,Length(b)+1); b[index]:=0; end; if b[index]=0 then begin b[index]:=1; flag:=true; end else begin b[index]:=0; inc(index); end; end; end; procedure DecBinary(var b: TBitArray); var flag: boolean; index: integer; begin flag:=false; index:=0; while not flag do begin if b[index]=1 then begin b[index]:=0; flag:=true; end else begin b[index]:=1; inc(index); end; end; while (Length(b)>0)and(b[Length(b)-1]=0) do SetLength(b,Length(b)-1); end; function Dec2Bin (dec: string): string; var BinArr: TBitArray; DecArr: TDecArray; begin SetLength(BinArr,0); SetLength(DecArr,0); StrToDecArr(dec,DecArr); while Length(DecArr)>0 do begin DecDecimal(DecArr); IncBinary(BinArr); end; BinArrToStr(BinArr,Result); end; function Bin2Dec (bin: string): string; var BinArr: TBitArray; DecArr: TDecArray; begin SetLength(BinArr,0); SetLength(DecArr,0); StrToBinArr(bin,BinArr); while Length(BinArr)>0 do begin IncDecimal(DecArr); DecBinary(BinArr); end; DecArrToStr(DecArr,Result); end; end. Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj Последний раз редактировалось PhoeniX, 08.07.2010 в 00:38. |
#2
|
||||
|
||||
![]() Эмм.. если честно, то лень сейчас разбирать чужой код, но если тебе интересна эта тема, то выкладываю исходник для преобразования чисел из одной системы счисления в другую, исходная и конечная система счисления должны находиться в диапазоне [2..36].
Написано в далёком 2006 и имеет пару ошибок, вроде переполнения... Велик и могуч наш Object Pascal ! ICQ: 357-591-887 |
#3
|
|||
|
|||
![]() Думаю:
Код Код:
while (Length(s)>0)and(s[1] in [#10,#13,#32,#9]) do Delete(s,1,1); while (Length(s)>0)and(s[Length(s)] in [#10,#13,#32,#9]) do Delete(s,Length(s),1); Код:
for i := Length(s) DownTo 1 Do If Not (s[i] In ['0'..'9']) Then Delete(s,i,1); Тогда функция CharToDec примет вид: Код:
function CharToDec (c: char): TDecimal; begin Result:=ord(c)-48 end; И вообще, кому-то я тут писал код, который некоторое число конвертит в битовую строку и обратно. Кстати, даже с некоторой упаковкой по сравнению с твоим кодом. Правда, это была не честная конвертация, а для передачи данных в битовом образе. |
#4
|
||||
|
||||
![]() Я уже сказал, что это мне не подходит.
Про замечания знаю, но это не особо ускорит сам процесс преобразования. Мне надо бы как-либо ускорить код функций IncBinary, IncDecimal, DecBinary и DecDecimal... Я уже думал просмотреть код в ассемблере, и переписать функцию на нём... Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj |
#5
|
||||
|
||||
![]() DJ PhoeniX, а зачем ты так заморачиваешься с типами TBit, TDec? Один хрен размер = 1 байт
![]() ![]() |
#6
|
||||
|
||||
![]() Мне нужна быстрая работа с числами ЛЮБЫХ размеров, а всё готовые методы ограничены в пределах Integer, максимум Int64...
Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj |
#7
|
||||
|
||||
![]() Вот. Совместил в одной программе твой модуль и свой
![]() ![]() З.Ы. число в 500 символов конвертится за 187мс (из 10 в 2), 3000 за 7сек. а обратно за 343 мс и 16сек соответственно. Твой метод умирает уже на 8-10 символах. З.З.Ы. Сильно не критиковать...вобще ничего не оптимизировал...думаю, поработав еще чуток, можно и мой результат улучшить в разы. Последний раз редактировалось dr. F.I.N., 12.01.2012 в 17:09. |
#8
|
||||
|
||||
![]() Бл... *цензура*...
![]() Как я сразу не допёр до этого решения... *i'm looser, epic fail ![]() Лови + в репутацию... ![]() Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj |
#9
|
||||
|
||||
![]() А вообще, я бы попробывал взять класс для работы с очень длинными числами и оптимизировать его под твою задачу (сложение, деление на 2, степень 2). А учитывая, что есть реализации на асме - вообще можно очень шустро все реализовать.
|
#10
|
||||
|
||||
![]() Очень длинными - это какими? Самый "большой" формат, который я знаю - это int64, но он ограничен достаточно небольшой длиной... А мне нужно обрабатывать числа длиной до 256 цифр.
Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj |
#11
|
||||
|
||||
![]() Вчера дома находил класс реализующий очень длинные числа...но сегодня с работы не могу вспомнить какой запрос построил
![]() На данный момент нашел набор функций. Но лично мне он не нравится. |