|
|
Conținut
longnum.pasx unit LongNum; {------------------------------------------------------------------------} interface uses dos, crt, strings; {------------------------------------------------------------------------} const maxBuf = 1024; {4..65535} tmpName = '_lnm'; numExt = '.num'; M1 = $FF; S1 = $80; chZero = $30; {cod ASCII} {------------------------------------------------------------------------} type TBufSize = 0..maxBuf; TBuf = record len: TBufSize; s: PChar; end; PBuf = ^TBuf; BFile = file of byte; {------------------------------------------------------------------------} var AddOverFlow: boolean; {------------------------------------------------------------------------} { Operatii cu numere file } {------------------------------------------------------------------------} { src <> dst si src1 <> src2 sunt conditii necesare rs - valoarea ramasa de la ultima operatie by - factor sau impartitor } procedure fAdd(var src1, src2, dst: BFile); procedure fMul(var src: BFile; by: word; rs: word); function fDiv(var src: BFile; by: word): word; {intoarce restul impartirii} function fNeg (var src, dst: BFile): byte; {intoarce byte-ul superior din dst} function fReduce(var src: BFIle): byte; {reduce octetii inutili din src} procedure fReverse(var src, dst: BFile); {inverseaza ordinea octetilor in src} function fIsNull(var src: BFile): boolean; {verifica daca valoarea src este 0} {Functii de conversie dintre formele binara si textual-zecimala} function fBin2Dec(var src, dst: BFile): longint; function fDec2Bin(var src, dst: BFile): longint; {------------------------------------------------------------------------} { Operatii cu numere string } {------------------------------------------------------------------------} {Aceste functii sunt proiectate pentru a fi chemate de catre functiile ce opereaza pe fisiere, de aceea nu recomand utilizarea lor independenta daca nu intelegi mecanismul lor de functionare } function sAdd(var src, dst: TBuf; rs: word): word; {signed operations} function sDiv(var src: TBuf; by: word; rs: word): word; function sMul(var src: TBuf; by: word; rs: word): word; function sNot(var src: TBuf): byte; {Intoarce ultimul byte} function sNeg(var src: TBuf; rs: byte): byte; function sReduce(var src: TBuf): TBufSize; function sReverse(var src: TBuf): TBufSize; function snAdd(var src: TBuf; n: word): word; {------------------------------------------------------------------------} { Functii ajutatoare } {------------------------------------------------------------------------} function readBufDec(var src: BFile; var buf: TBuf; nr: TBufSize): TBufSize; function readBuf (var src: BFile; var buf: TBuf): TBufSize; function writeBuf(var dst: BFile; var buf: TBuf): TBufSize; function copyFile(var src, dst: BFile): longint; function fileExists(fn: string): boolean; function tempFileName: string; function tempFile(var f: BFile): string; function setBLen(var src: TBuf; l: TBufSize): TBufSize; function Str2Buf(st: string; var b: TBuf): TBufSize; {------------------------------------------------------------------------} implementation {$I-} {------------------------------------------------------------------------} var { b - la citirea/scrierea datelor din/in fisier g - operatii cu semnul numarului w - counter la citire/scriere r - restul de la operatia precedenta pcl si pcr - pointeri la lr si r, respectiv plX - pointer la lr incepand cu octetul X Daca lr ::= (00, 01, 02, 03), atunci pl0^ ::= (00, 01), pl1^ ::= (01, 02), pl2^ ::= (02, 03) Am avut in vedere faptul ca octetii intr-o variabila de tip longint (4 la numar) sunt aranjati de la cel de jos spre cel de sus in memorie. } b, g: byte; w, r: word; lr: longint; pcl, pcr: PChar; pl0, pl1, pl2: ^Word; buf1, buf2: TBuf; {------------------------------------------------------------------------} function setBLen(var src: TBuf; l: TBufSize): TBufSize; var i: TBufSize; p: Pointer; begin if l < 0 then l := 0; if l > maxBuf then l := maxBuf; i := src.len; if i <> l then with src do begin p := s; len := l; if l = 0 then s := nil else begin GetMem(s, l); if l > i then l := i; StrMove(s, p, l); end; FreeMem(p, i); end; setBLen := src.len; end; {------------------------------------------------------------------------} function Str2Buf(st: string; var b: TBuf): TBufSize; begin setBLen(b, length(st)); StrPCopy(b.s, st); Str2Buf := b.len; end; {------------------------------------------------------------------------} procedure fAdd(var src1, src2, dst: BFile); var f: ^BFile; begin reset (src1); reset (src2); rewrite(dst); r := 0; while not (eof(src1) or eof(src2)) do begin readBuf(src1, buf1); readBuf(src2, buf2); sAdd(buf1, buf2, r); writeBuf(dst, buf2); end; g := $00; if eof(src2) then begin f := @src1; with buf2 do if (len <> 0) and (ord(s[len-1])and S1 <> 0) then g := M1; end else begin f := @src2; with buf1 do if (len <> 0) and (ord(s[len-1])and S1 <> 0) then g := M1; end; while ( (r xor g)and 1 <> 0 ) and not eof(f^) do begin readBuf(f^, buf2); snAdd(buf2, r); writeBuf(dst, buf2); end; while not eof(f^) do begin readBuf(f^, buf2); writeBuf(dst, buf2); end; end; {------------------------------------------------------------------------} function fNeg (var src, dst: BFile): byte; begin reset (src); rewrite(dst); r := 1; while (readBuf(src, buf1) or r) > 0 do begin sNeg(buf1, r); writeBuf(dst, buf1); end; fNeg := b; end; {------------------------------------------------------------------------} function sReduce(var src: TBuf): TBufSize; begin r := src.len; if r > 1 then with src do begin dec(r); g := ord(s[r]); if (g = $00) or (g = M1) then begin repeat dec(r); b := ord(s[r]); until (g <> b)or(r = 0); if (g xor b) and S1 <> 0 then inc(r); setBLen(src, r+1); end; end; sReduce := src.len; end; {------------------------------------------------------------------------} function fReduce(var src: BFIle): byte; begin reset(src); lr := FileSize(src); if lr = 0 then g := 0 else begin dec(lr); seek(src, lr); read(src, g); if (lr > 0) and ((g = $00) or (g = M1)) then begin repeat dec(lr); seek(src, lr); read(src, b); until (g <> b) or (lr = 0); if (g xor b) and S1 <> 0 then inc(lr); seek(src, lr+1); truncate(src); end; end; fReduce := g; end; {------------------------------------------------------------------------} function sReverse(var src: TBuf): TBufSize; var c: char; begin with src do if len > 0 then begin r := len div 2; dec(len); while r > 0 do begin dec(r); c := s[r]; s[r] := s[len-r]; s[len-r] := c; end; inc(len); end; sReverse := src.len; end; {------------------------------------------------------------------------} procedure fReverse(var src, dst: BFile); var l: longint; begin reset(src); rewrite(dst); l := FileSize(src); l := l - ((l-1) mod maxBuf + 1); repeat seek(src, l); readBuf(src, buf2); sReverse(buf2); writeBuf(dst, buf2); dec(l, maxBuf); until l < 0; end; {------------------------------------------------------------------------} function fIsNull(var src: BFIle): boolean; begin reset(src); b := 0; while not eof(src) and (b=0) do read(src, b); fIsNull := b=0; end; {------------------------------------------------------------------------} function fBin2Dec(var src, dst: BFile): longint; var sn: byte; l : longint; f : BFile; begin fReduce(src); if g and S1 <> 0 then begin sn := ord('-'); fNeg(src, dst); end else begin sn := ord('+'); copyFile(src, dst); end; tempFile(f); setBLen(buf1,4); repeat fDiv(dst, 10000); {in lr se obtine restul de la impartire} for b := 0 to 3 do with buf1 do begin s[b] := chr((lr mod 10) + chZero); lr := lr div 10; end; writeBuf(f, buf1); fReduce(dst); until fIsNull(dst); l := FileSize(f); if l = 0 then begin b := 0; write(f, b); inc(l); end else begin b := chZero; while (b=chZero)and(l>0)do begin dec(l); seek(f, l); read(f, b); end; if l = 0 then inc(l); seek(f, l+1); truncate(f); if sn = ord('-') then write(f, sn); end; fReverse(f, dst); fBin2Dec := FileSize(dst); close(f); erase(f); end; {------------------------------------------------------------------------} function fDec2Bin(var src, dst: BFile): longint; var sn: byte; f : BFile; i : word; begin rewrite(dst); reset(src); read(src, sn); reset(src); repeat i := readBufDec(src, buf1, 4); w := 1; r := 0; b := 0; while b < i do with buf1 do begin r := 10*r + (ord(s[b])-chZero); w := 10*w; inc(b); end; if w > 1 then fMul(dst, w, r); until i < 4; seek(dst, FileSize(dst)); b := $00; write(dst, b); {numar pozitiv} fReduce(dst); if sn = ord('-') then begin tempFile(f); {close(f); reset(f);} fNeg(dst, f); copyFile(f, dst); close(f); erase(f); end; fDec2Bin := FileSize(dst); end; {------------------------------------------------------------------------} function snAdd(var src: TBuf; n: word): word; var l: word; begin r := n; if src.len > 0 then with src do begin l := 0; while ( (g xor r)and 1 <> 0 ) and (l < len) do begin inc(r, ord(s[l]) + g); s[l] := chr(r and M1); r := r shr 8; inc(l); end; end; snAdd := r; end; {------------------------------------------------------------------------} function sAdd(var src, dst: TBuf; rs:word): word; var i, m: word; lw, hg: PBuf; begin g := 0; if dst.len > src.len then begin lw := @src; hg := @dst; end else begin lw := @dst; hg := @src; end; m := lw^.len; {Pana la m exista cifre si in dst, si in src} if (m > 0) and (ord(lw^.s[m-1])and S1 <> 0) then g := M1 else g := 0; {Semnul nr mai mic} r := rs; {Restul de la operatia precedenta} i := 0; while (i < m) do begin inc( r, ord(dst.s[i]) + ord(src.s[i]) ); dst.s[i] := chr(Lo(r)); r := Hi(r); inc(i); end; if i < hg^.len then begin m := setBLen(dst, hg^.len); {Pana la m exista cifre numai in hg^} while ( (r xor g)and 1 <> 0 ) and (i < m) do begin inc( r, ord(hg^.s[i]) + g ); dst.s[i] := pcr[0]; r := Hi(r); inc(i); end; {In locul buclei de mai sus pot fi folosite urmatoarele doua bucle} { if( g and $80 <> 0 ) then while (r = 0) and (i < m) do begin inc( r, ord(hg^.s[i]) + M1 ); dst.s[i] := chr(Lo(r)); r := Hi(r); inc(i); end else while (r <> 0) and (i < m) do begin inc( r, ord(hg^.s[i]) ); dst.s[i] := chr(Lo(r)); r := Hi(r); inc(i); end; } if hg<>@dst then while (i < m) do begin dst.s[i] := src.s[i]; inc(i); end; end; sAdd := r; end; {------------------------------------------------------------------------} function sMul(var src: TBuf; by: word; rs: word): word; var i: word; begin with src do begin r := rs; lr := 0; i := 0; while (i+1<len) do begin {32 bits} pcl[0]:= s[i]; pcl[1]:= s[i+1]; lr := lr * by + r; s[i] := pcl[0]; inc(i); s[i] := pcl[1]; inc(i); r := pl2^; pl2^ := 0; end; if i<len then begin {16 bits} pl1^ := 0; pcl[0]:= s[i]; lr := lr * by + r; s[i] := pcl[0]; inc(i); r := pl1^; end; if AddOverFlow and (len < maxBuf)and(r <> 0) then begin if( pcr[1] <> #0) then begin setBLen(src, i+2); s[i]:= pcr[0]; inc(i); s[i]:= pcr[1]; end else begin setBLen(src, i+1); s[i]:= pcr[0]; end; r := 0; end; end; sMul := r; {se intoarce valoarea aflata in lr - ceea ce nu a incaput in maxBuf bytes} end; {------------------------------------------------------------------------} procedure fMul(var src: BFile; by: word; rs: word); var aof: boolean; begin reset (src); r := rs; aof := AddOverFlow; repeat readBuf(src, buf2); AddOverFlow := w = 0; sMul(buf2, by, r); seek(src, filePos(src)-w); writeBuf(src, buf2); until (r = 0) and eof(src); AddOverFlow := aof; end; {------------------------------------------------------------------------} { Imparte numarul continut in s la by si intoarce restul acestei impartiri } function sDiv(var src: TBuf; by: word; rs: word): word; var i: word; begin pl0^ := rs; with src do begin i := len; while (i>1) do begin {32 bits} dec(i, 2); pl2^ := pl0^; pcl[0]:= s[i]; pcl[1]:= s[i+1]; r := lr div by; lr := lr mod by; s[i] := pcr[0]; s[i+1]:= pcr[1]; end; if i>0 then begin {16 bits} dec(i); pl1^ := pl0^; pcl[0] := s[i]; r := lr div by; lr := lr mod by; s[i] := pcr[0]; end; end; sDiv := lr; {se intoarce valoarea aflata in lr - restul impartirii la by a shirului} end; {------------------------------------------------------------------------} function fDiv(var src: BFile; by: word): word; var l: longint; begin reset (src); lr := 0; l := FileSize(src); l := l - ((l-1) mod maxBuf + 1); repeat seek(src, l); readBuf(src, buf2); sDiv(buf2, by, lr); seek(src, l); writeBuf(src, buf2); dec(l, maxBuf); until l < 0; fDiv := lr; end; {------------------------------------------------------------------------} function sNot(var src: TBuf): byte; begin r := 0; if src.len = 0 then begin setBLen(src, 1); src.s[0] := #$FF; end else with src do while r<len do begin s[r] := chr(not ord(s[r])); inc(r); end; sNot := ord(src.s[r-1]) end; {------------------------------------------------------------------------} function sNeg(var src: TBuf; rs: byte): byte; var l: word; begin r := rs; l := 0; with src do while l<len do begin inc(r, not ord(s[l])); s[l] := chr(lo(r)); r := hi(r); inc(l); end; sNeg := r; end; {------------------------------------------------------------------------} function readBufDec(var src: BFile; var buf: TBuf; nr: TBufSize): TBufSize; {Aceasta functie citeste nr octeti din src, si numai cifre zecimale Intoarce nr de octeti cititi din src, iar restul octetilor din buf, pana la nr, sunt completati cu #0 } begin w := 0; setBLen(buf, nr); while not eof(src) and (w<nr) do begin read(src, b); if b in [chZero..chZero+9] then begin buf.s[w] := chr(b); inc(w); end; end; readBufDec := w; while w<nr do with buf do begin s[w] := #0; inc(w); end; end; {------------------------------------------------------------------------} function readBuf(var src: BFile; var buf: TBuf): TBufSize; begin w := 0; if eof(src) then begin readBuf := 0; setBLen(buf,0); exit; end; setBLen(buf, maxBuf); while not eof(src) and (w<maxBuf) do begin read(src, b); buf.s[w] := chr(b); inc(w); end; if w<maxBuf then setBLen(buf, w); readBuf := w; end; {------------------------------------------------------------------------} function writeBuf(var dst: BFile; var buf: TBuf): TBufSize; begin w := 0; while w<buf.len do begin b := ord(buf.s[w]); write(dst, b); inc(w); end; writeBuf := w; end; {------------------------------------------------------------------------} function copyFile(var src, dst: BFile): longint; var r: longint; begin r := 0; reset(src); rewrite(dst); repeat readBuf(src, buf2); inc(r, w); writeBuf(dst, buf2); until w < maxBuf; copyFile := r; end; {------------------------------------------------------------------------} function fileExists(fn: string): boolean;var Dir: SearchRec; begin findFirst(fn, $3F, Dir); fileExists := DosError = 0; end; {------------------------------------------------------------------------} function tempFileName: string; var t: string; begin t := getenv('temp')+'\'+tmpName+'AAA.tmp'; b := length(t)-4; while fileExists(t) do begin if t[b] = 'Z' then begin t[b]:='A'; if t[b-1]='Z' then begin t[b-1]:='A'; if t[b-2]='Z' then t[b-2]:='A' else inc(char(t[b-2])) end else inc(char(t[b-1])) end else inc(char(t[b])); end; tempFileName := t; end; {------------------------------------------------------------------------} function tempFile(var f: BFile): string; var fn: string; begin fn := tempFileName; assign(f, fn); rewrite(f); tempFile := fn; end; {------------------------------------------------------------------------} procedure Init; var p: Pointer; begin buf1.s := nil; buf2.s := nil; buf1.len := 0; buf2.len := 0; AddOverFlow := true; g := 0; p := @r; pcr := p; p := @lr; pl0:= p; pcl := p; p := pcl + 1; pl1:= p; p := pcl + 2; pl2:= p; end; {------------------------------------------------------------------------} begin Init; end. Aici acumulez programe şi algoritmi interesanti alcătuiţi de mine (cu mici excepţii) pe parcursul studierii unor limbaje de programare. Cea mai mare parte din ele sunt realizate în Pascal. Nu am scopul creării unui curs specializat sau a descrierii detaliate a anumitor limbaje, ci doar prezint informaţii utile, plus ceva exemple interesante...
Răsfoitorul de fișiere (File Browser):Codul sursă al programelor este organizat în mape şi fişiere. Paginile care conțin cod sursă de programe de regulă au un răsfoitor de fișiere în partea stangă a paginii reprezentat de un bloc cu titlul „File Browser”. Pentru a vizualiza un program sau conţinutul unei mape, faceţi click pe numele fişierului / mapei. Dacă fişierul nu este textual, el se va descărca automat, iar dacă este textual, conținutul lui se va afișa într-un bloc pe centrul paginii. Pentru a descărca un fişier, faceţi click pe dimensiunea (size) lui.
Căutare
|