hexadecimal, binere og 10-talssystem

Tags:    delphi

Hej alle...

Man kan selvfølgelig altid begynde at sætte tabeller op, med hexadecimalkoder og binere koder og så få Delphi til at slå op i disse for at omsætte det til 10-talsystemet...
However.....

Er der nogen der kender til en hurtig lille og nem måde, hvorpå man kan omsætte de forskellige tal... Lidt ligesom oversættelsen mellem string og integer...?

Det ville lette mit arbejde en del, da jeg skal have omsat en hel del binere tal til 10-talssystemet og omvendt, i et kommende projekt....

-> På forhånd tak...



6 svar postet i denne tråd vises herunder
1 indlæg har modtaget i alt 3 karma
Sorter efter stemmer Sorter efter dato
<pre>function BinToInt(BinaerString: String): Integer;
var I: Integer;
BinTaeller: Integer;
Heltal: Integer;
begin
Heltal := 0;
BinTaeller := 1;
for I := 1 to Length(BinaerString) do
begin
if I > 1 then BinTaeller := BinTaeller + BinTaeller;
if BinaerString[Length(BinaerString) - I + 1] = '1' then
Heltal := Heltal + BinTaeller;
end;
Result := Heltal;
end;</pre>Det det sker her er at en løkke kører den Binære værdi igennem og siger: Pladsens værdi (fx 32 16 8 4 2 1) skal fordobles (undtagen første gang da den starter med at være 1). Hvis så at det tegn den er nået til er et 1-tal (Længden - I (1..Længden) + 1 = Højre mod venstre) så bliver pladsens værdi lagt til summen.

<pre>function IntToBin(Heltal: Integer): String;
var HoejesteTal: Extended;
HeltalTemp: Integer;
BinaerString: String;
begin
HeltalTemp := Heltal;
HoejesteTal := Trunc(Log2(HeltalTemp));
HoejesteTal := Power(2, HoejesteTal);
BinaerString := '1';
HeltalTemp := HeltalTemp - Round(HoejesteTal);

repeat
HoejesteTal := HoejesteTal / 2;
if HeltalTemp - HoejesteTal >= 0 then
begin
BinaerString := BinaerString + '1';
HeltalTemp := HeltalTemp - Round(HoejesteTal);
end
else
BinaerString := BinaerString + '0';
until
HoejesteTal = 1;

Result := BinaerString;
end;</pre>1. linie: Indputtet bliver gemt midlertidigt (ikke nødvendigt).

HoejesteTal er et kommatal (extended) der bliver brugt til at finde ud af det højeste af tallene 1, 2, 4, 8, 16, osv som Indputtet kan være i.

For at forstå 2. linie må du lige vide at 1, 2, 4, 8, ... er det samme som 2^0, 2^1, 2^2, 2^3, ...

2. linie: Det første tal skal findes, Trunc() fjerner decimalerne og Log2() gør det modsatte 2^n (fx Log2(8) = 3).

Power(Base, Exp) er det samme som Base^Exp.

3. linie: Her bliver der fundet det første tal fundet ved hjælp af tallet fra linie 2.

Grunden til at vi først skal gå den ene vej og så tilbage igen er at vi skal have fjernet "resten" (fx hvis indputtet er 10 skal tallet være 8, Log2(10) = 3,.. ca 3).

4. linie: Den binære værdi starter med et 1-tal til venstre.

5. linie: Det første Bintal bliver trukket fra. Round() er normalt til at afrunde kommatal, men vi bruger den til at omdanne et kommatal til et heltal.

Repeat/until løkken:

Løkken kører indtil det sidste bintal er kørt igennem.

1. linie: Det første bintal bliver halveret for at få det næste bintal.

2. - 8. linie: En if-sætning ser om det bintal vi er nået til kan være i det vi har tilbage fra indputtet og hvis det kan tilføjes der et 1-tal til den binære værdi og Bintallet bliver trukket fra Indputtet ellers tilføjes der bare et 0.

Emil Melgaard
emil.melgaard@private.dk
- Admin på gruppen Delphi spilprogrammering.
http://www.delphispilprogram.udvikleren.dk



Hej alle...

Man kan selvfølgelig altid begynde at sætte tabeller op, med hexadecimalkoder og binere koder og så få Delphi til at slå op i disse for at omsætte det til 10-talsystemet...
However.....

Er der nogen der kender til en hurtig lille og nem måde, hvorpå man kan omsætte de forskellige tal... Lidt ligesom oversættelsen mellem string og integer...?

Det ville lette mit arbejde en del, da jeg skal have omsat en hel del binere tal til 10-talssystemet og omvendt, i et kommende projekt....

-> På forhånd tak...


Til konvertering mellem Hex og Binær kan HexToBin() og BinToHex() bruges (slå dem op i hjælpen.

Jeg kan ikke lige finde nogle funktioner til oversættelse mellem 10-tal og binær, men her har du nogle hjemmelavede, Hvis du gerne vil have at jeg forklarer dem, så skal du bare skrive.

Jeg ved at BinToInt kan laves simplere (med 2^x) men jeg kunne ikke lige få det til at virke.

Her er de, BinToInt() og IntToBin():

<pre>function BinToInt(BinaerString: String): Integer;
var I: Integer;
BinTaeller: Integer;
Heltal: Integer;
begin
Heltal := 0;
BinTaeller := 1;
for I := 1 to Length(BinaerString) do
begin
if I > 1 then BinTaeller := BinTaeller + BinTaeller;
if BinaerString[Length(BinaerString) - I + 1] = '1' then
Heltal := Heltal + BinTaeller;
end;
Result := Heltal;
end;

function IntToBin(Heltal: Integer): String;
var HoejesteTal: Extended;
HeltalTemp: Integer;
BinaerString: String;
begin
HeltalTemp := Heltal;
HoejesteTal := Trunc(Log2(HeltalTemp));
HoejesteTal := Power(2, HoejesteTal);
BinaerString := '1';
HeltalTemp := HeltalTemp - Round(HoejesteTal);

repeat
HoejesteTal := HoejesteTal / 2;
if HeltalTemp - HoejesteTal >= 0 then
begin
BinaerString := BinaerString + '1';
HeltalTemp := HeltalTemp - Round(HoejesteTal);
end
else
BinaerString := BinaerString + '0';
until
HoejesteTal = 1;

Result := BinaerString;
end;</pre>Emil Melgaard
emil.melgaard@private.dk
- Admin på gruppen Delphi spilprogrammering.
http://www.delphispilprogram.udvikleren.dk[Redigeret d. 03/03-03 22:19:28 af Emil Melgaard]



Værs'go

Her er mine egne to funktioner til binær konverting til og fra streng.
Du burde nemt kunne lave en 16 bit version af Int32ToBinStr selv.

function Int32ToBinStr(i : cardinal) : string;

var bit : byte;
isset : boolean;

begin
result := '';
for bit := 0 to 31 do begin
isset := (i shr bit and 1) > 0;
if isset then result := '1' + result
else result := '0' + result;
end;
end;

function BinStrToInt32(binstr : string) : Cardinal;

var bit : integer;

begin
result := 0;
for bit := 1 to Length(binstr) do begin
result := result + (cardinal((binstr[-(bit - Length(binstr)) + 1] = '1')) * (1 shl (bit - 1)));
end;
end;

Som Emil skriver kan du bruge inttohex hvis du skal bruge en hex streng.
Hvis du har brug for at konvertere en hexstreng til en integer kan du gøre
således:

var tal : integer;

tal := strtoint( '$' + hexstring); // hvor hexstring f.eks er = '3ffa';

Bemærk $ tegnet som bliver indsat i hexstring. Det høv's sæfø'li ikke hvis det allerede er det.


Håber at du kan bruge det til noget, om end mine funktioner nok kan forekomme at være
det rene volapyk for det utrænede øje (men de virker altså...nå ;-)




function IntToBaseX(num: integer; bas: integer): string;
var
n: integer;

function toChar(n: integer): char;
begin
if n<10 then result:=chr(ord('0')+n)
else result:=chr(ord('A')+n-10);
end;

begin
n:=num;
result:='';
repeat
result:=toChar(n mod bas)+result;
n:=n div bas
until n=0;
end;

function BaseXtoInt(num: string; bas: integer): integer;
var
i: integer;
n: integer;

function getChar(c: char): integer;
begin
if c<='9' then result:=ord(c)-ord('0')
else result:=ord(c)-ord('A')+10;
end;

begin
result:=0;
for i:=1 to length(num) do
result:=result*bas+getChar(num); //hvor er []
end;[Redigeret d. 11/03-03 11:11:04 af Martin Klausen Andersen]




function intToBin(num: integer): string;
var
n: integer;
begin
n:=num;
result:='';
repeat
result:=chr(48+(n and 1))+result;
n:=n shr 1;
until n=0
end;

Bare lige for sjov, har ikke lige prøvet men den er vist ok.

Ellers har du vel snart svaret, den jeg postede "ovenfor" kan alle baser, fra 2 til 36 uden at give forkerte tegn, og det er begge veje.
Både BaseXtoInt og IntToBaseX er begge testede, der er en begrænsning på 31 bit ca 2.000.000.000 og uden fortegn eller komma, men det kan nemt bygges ind. Størrelses begrænsningen kan flyttes med brug af real-type istedet for integer.

ups> der var da en lille fejl i BaseXtoInt, getChar(num) skal være getChar(num) OK !!
[Redigeret d. 10/03-03 13:10:16 af Martin Klausen Andersen]




Øjensynlig så filtreres skarpe parenteser fra på min skærm(!), får da jeg prøvede at redigere det jeg havde skrevet i mit første indlæg så var de faktisk i koden ??
Men det kan vel være ligemeget for spørger deltager jo alligevel ikke, og han lukker ikke sit spørgsmål, man skulle ellers tro at han havde et svar nu.



t