Delphi - Számrendszerek kezelése 2-től 36-ig

forráskód letöltése
Ha különböző számrendszerekkel dolgozunk, jól jöhet egy olyan komponens, ami a 2-estől a 36-os számrendszerig oda-vissza képes konvertálni a megadott értéket. A mellékelt példaprogram megnyitása előtt a Radix.pas-ban lévő komponenst telepítenie kell a Delphi alá.

Ugyan a komponens property-jein keresztül csak tízes számrendszerbe, illetve számrendszerből tudunk konvertálni, de a komponens tartalmaz 3 függvényt is a további konverziókhoz.
A Decimal property-ben megadhatjuk azt a 10-es számrendszerbeli számot, amit konvertálni akarunk. A NumericSystem annak a számrendszernek az alapja, amibe, illetve amiből konvertálni akarunk, így ennek értéke 2-36 lehet. A Number property-ben megkapjuk az adott számrendszerbeli eredményt. Ha a Number property-t módosítjuk, akkor annak megfelelően fog változni a Decimal property értéke is. Ha a Decimal, vagy NumericSystem property-ket módosítjuk, akkor a Number property értéke változik ennek megfelelően.
A DecimalToSystem függvény tízes számrendszerből a megadott számrendszerbe konvertál, míg a SystemToDecimal a megadott számrendszerből tízes számrendszerbe. Mindkét függvény a Convert függvényt használja, amivel bármelyik számrendszerből bármelyikbe lehet konvertálni. Mivel Delphi-ből csak a tízes illetve tizenhatos számrendszer használható közvetlenül, ezért a függvény visszatérési értéke egy sztring, ami az adott számrendszerbeli szám számjegyeit tartalmazza, valamint a value paraméter, amit konvertálni kell szintén sztringben van megadva.
function TRadix.Convert(nsfrom, nsto: TNumericSystem; value: string): string;
A függvény első részében a paraméterként megadott értéket (value) átszámítjuk tízes számrendszerbe. Az nsfrom paraméter az a számrendszer, amiből konvertálni akarunk, ezért itt ezt kell felhasználnunk. A számjegyeken végighaladunk jobbról-balra, és az adott pozícióban lévő számjegy (ami 11-es számrendszertől felfelé akár betű is lehet) értékét megszorozzuk a számrendszer adott pozícióhoz tartozó értékével. Az első számjegyet minden esetben 1-el, majd a számrendszer alapjául szolgáló szám hatványaival.
  npos:=1;
  res:=0;
  p:=Length(value);
  while p>0 do begin
    num:=Pos(UpCase(value[p]), numbers)-1;
    inc(res, num*npos);
    npos:=npos*nsfrom;
    dec(p);
  end;
A res változóban tároljuk a szám tízes számrendszerbeli értékét. Mivel a másik számrendszerbe való konvertáláskor először a legnagyobb helyi értékkel kell osztanunk, ezért egy egyszerű ciklusban kiszámoljuk, hogy ez mennyi lesz. Például, ha az FF tizenhatos számrendszerbeli számot konvertáljuk 8-asba, akkor a res változó értéke 255 lesz. A 8-as számrendszerbe a helyi értékek így követik egymást: 1, 8, 64, 512, 4096, stb., tehát a 8 hatványai. Az már rögtön látszik, hogy 512-vel nem érdemes osztani, mivel az eredmény 0, és a 0-t minden szám elejéről elhagyjuk. Az első szám, amivel osztani kell a 64. Minden osztásnál csak az egész eredményt vesszük figyelembe. Az eredmény tehát 3, így ez lesz az első számjegy. A maradék 63, amit viszont már csak 8-al kell osztani. Az eredmény most 7, és a maradék is ennyi, tehát a nyolcas számrendszerbeli szám: 377.
  npos:=1;
  res:=Abs(res);
  while (res div (npos*nsto))>0 do npos:=npos*nsto;
Ha tehát megvan az a legnagyobb érték, amivel osztani kell, akkor egy ciklusban végigosztjuk a megfelelő értékekkel a számot, és a v változóban eltároljuk a megfelelő számjegy karaktert. Ezt a numbers konstans sztringből vesszük. Minden osztás után csak a maradékkal foglalkozunk tovább, így a ciklus végén előáll a teljes szám a megfelelő számjegyekkel.
  v:='';
  while npos>0 do begin
    v:=v+numbers[(res div npos)+1];
    res:=res mod npos;
    npos:=npos div nsto;
  end;
  result:=v;