Számrendszerek, algoritmusok


Példák algoritmusokra

Az tárgyalt algoritmusok leírását a legtöbb esetben rövid JavaScript programokkal is bemutatjuk. A példák kipróbálásához felhasználható online JavaScript interpreter:

Online JavaScript Interpreter by Peter Jipsen, Chapman University (January 2013).
http://math.chapman.edu/~jipsen/js/ (2020-11-19)

Megjegyzés: Ha a fenti link valamilyen oknál fogva nem működik, használjuk az alábbi linket.

A JavaScript programok folyamatábráját megjeleníthetjük az alábbi webes alkalmazás segítségével:

Live code editor. Created by Bogdan Lyashenko.
https://bogdan-lyashenko.github.io/js-code-to-svg-flowchart/docs/live-editor/index.html (2022-10-02)

A folyamatábra a 'for' ciklust nem megfelelően ábrázolja, ezért érdemes ezeket mindig átírni 'while' ciklusra, mielőtt megjelenítenénk a program folyamatábráját.



Példák algoritmusokra:
1. bináris szám átalakítása decimális számmá

Szótár:
– bináris számok = kettes számrendszerbeli számok
– decimális számok = tízes számrendszerbeli számok

Példa: 11012 = ?10

számjegy helyi érték szorzat
1 23=8 8
1 22=4 4
0 21=2 0
1 20=1 1
Összesen 13

Eredmény:
11012 = 1310

Ellenőrzés:
1310 = 8 + 4 + 1 = 1*23 + 1*22 + 0*21 + 1*20 = 11012 (ok)


A fenti algoritmust megvalósító JavaScript program:

// bináris szám átalakítása decimális számmá 

var x="1101";

writeln("Bináris szám: "+x);
writeln();

var d=0;
var helyiertek=1;

for(var i=1;i<x.length;i++) {
 helyiertek*=2;
 }

for(var i=0;i<x.length;i++) {
 var sz;
 if(x[i]=="1") {
  sz=1;
  }
 else {
  sz=0;
  }
 writeln("   Számjegy   : "+sz);
 writeln("   Helyi érték: "+helyiertek);
 var r=sz*helyiertek;
 writeln("      Részösszeg: "+r);
 d+=r;
 helyiertek/=2;
 }

writeln();

writeln("Decimális szám: "+d);

writeln("__________");

A fenti JavaScript program egyszerűsített változata és ennek a folyamatábrája a következő:

// bináris szám átalakítása decimális számmá (ver 2.0)

var x="1101"; 

writeln("Bináris szám: "+x);
writeln();

var d=0;
var helyiertek=1;

var i=1;
while(i<x.length) {
 helyiertek=helyiertek*2;
 i=i+1;
 }

i=0;
while(i<x.length) {
 var sz;
 if(x[i]=="1") {
  sz=1;
  }
 else {
  sz=0;
  }
 var r=sz*helyiertek;
 d=d+r;
 helyiertek=helyiertek/2;
 i=i+1;
 }

writeln("Decimális szám: "+d);

writeln("__________");

A fenti JS program (bin2dec) folyamatábrája

A fenti JavaScript programokban előforduló fontosabb programnyelvi szerkezetek rövid magyarázata megtalálható itt.


A bináris egész számokhoz hasonlóan tudjuk a bináris törtszámokat átváltani tizedestörtekké. A különbség csak az, hogy a törtszámok helyiértékei 2 negatív egész hatványai lesznek (a 2−1=1/2 helyiértéktől kezdődően).

Elég csak olyan számokkal foglalkoznunk, amelyek pozitívak és 1-nél kisebbek (azaz egész részük zérus), mivel egy bináris szám egész részét és törtrészét külön-külön átalakíthatjuk decimális számmá.

Példa: 0.11012 = ?10

számjegy helyi érték szorzat
1 2−1=1/2 1/2
1 2−2=1/4 1/4
0 2−3=1/8 0
1 2−4=1/16 1/16
Összesen 13/16

Eredmény:
0.11012 = 13/1610 = 0.812510

Ellenőrzés:
0.812510 = 0.5 + 0.25 + 0.0625 = 1*2−1 + 1*2−2 + 0*2−3 + 1*2−4 = 0.11012 (ok)


A fenti algoritmust megvalósító JavaScript program:

// bináris törtszám átalakítása decimális törtszámmá (tizedestörtté)

/* feltétel: a bináris törtszám pozitív és 1-nél kisebb, azaz 0<x<1 teljesül */

var x="0.1101"; 

writeln("Bináris törtszám: "+x);
writeln();

var d=0;
var helyiertek=1/2;

for(var i=2;i<x.length;i++) {
 var sz;
 if(x[i]=="1") {
  sz=1;
  }
 else {
  sz=0;
  }
 writeln("   Számjegy   : "+sz);
 writeln("   Helyi érték: "+helyiertek);
 var r=sz*helyiertek;
 writeln("      Részösszeg: "+r);
 d+=r;
 helyiertek/=2;
 }

writeln();

writeln("Decimális törtszám: "+d);

writeln("__________");



Példák algoritmusokra:
2. hexadecimális szám átalakítása decimális számmá

Szótár:
– hexadecimális számok = tizenhatos számrendszerbeli számok
– decimális számok = tízes számrendszerbeli számok

Példa: 24C16 = ?10

számjegy helyi érték szorzat
2 162=256 512
4 161=16 64
C 160=1 12
Összesen 588

Eredmény:
24C16 = 58810

Ellenőrzés:
58810 = 512 + 64 + 12 = 2*256 + 4*16 + 12* 1 = 2*162 + 4*161 + 12*160 = 24C16 (ok)


A fenti algoritmust megvalósító JavaScript program:

// hexadecimális szám átalakítása decimális számmá 

// var x=["2","4","C"]; 
var x="24C";

write("Hexadecimális szám: ");

for(var i=0;i<x.length;i++) {
 write(x[i]);
 }

writeln();
writeln();

var d=0;
var helyiertek=1;

for(var i=1;i<x.length;i++) {
 helyiertek*=16;
 }

for(var i=0;i<x.length;i++) {
 var sz;
 switch(x[i]) {
  case "a":
  case "A": sz=10; break;
  case "b":
  case "B": sz=11; break;
  case "c":
  case "C": sz=12; break;
  case "d":
  case "D": sz=13; break;
  case "e":
  case "E": sz=14; break;
  case "f":
  case "F": sz=15; break;
  default: 
   sz=parseInt(x[i]);  
  }
 writeln("   Számjegy   : "+sz);
 writeln("   Helyi érték: "+helyiertek);
 var r=sz*helyiertek;
 writeln("      Részösszeg: "+r);
 d+=r;
 helyiertek/=16;
 }

writeln();

writeln("Decimális szám: "+d);

writeln("__________");

A fenti JavaScript program egyszerűsített változata és ennek a folyamatábrája a következő:

// hexadecimális szám átalakítása decimális számmá (ver 2.0)

var x="24C";

write("Hexadecimális szám: "+x);
writeln();

var d=0;
var helyiertek=1;

var i=1;
while(i<x.length) {
 helyiertek=helyiertek*16;
 i=i+1;
 }

i=0;
while(i<x.length) {
 var sz;
 switch(x[i]) {
  case "a":
  case "A": sz=10; break;
  case "b":
  case "B": sz=11; break;
  case "c":
  case "C": sz=12; break;
  case "d":
  case "D": sz=13; break;
  case "e":
  case "E": sz=14; break;
  case "f":
  case "F": sz=15; break;
  default: 
   sz=parseInt(x[i]);  
  }
 var r=sz*helyiertek;
 d=d+r;
 helyiertek=helyiertek/16;
 i=i+1;
 }

writeln("Decimális szám: "+d);

writeln("__________");

A fenti JS program (hex2dec) folyamatábrája

A fenti JavaScript program megvalósítható egymásba ágyazott if-else szerkezetekkel is.

A program és ennek a folyamatábrája a következő:

// hexadecimális szám átalakítása decimális számmá (ver 3.0)

var x="24C";

write("Hexadecimális szám: "+x);
writeln();

var d=0;
var helyiertek=1;

var i=1;
while(i<x.length) {
 helyiertek=helyiertek*16;
 i=i+1;
 }

i=0;
while(i<x.length) {
 var sz;
 if(x[i]=="a" || x[i]=="A") {
  sz=10;
  }
 else if(x[i]=="b" || x[i]=="B") {
  sz=11;
  }
 else if(x[i]=="c" || x[i]=="C") {
  sz=12;
  }
 else if(x[i]=="d" || x[i]=="D") {
  sz=13;
  }
 else if(x[i]=="e" || x[i]=="E") {
  sz=14;
  }
 else if(x[i]=="f" || x[i]=="F") {
  sz=15;
  }
 else {
  sz=parseInt(x[i]);  
  }
 var r=sz*helyiertek;
 d=d+r;
 helyiertek=helyiertek/16;
 i=i+1;
 }

writeln("Decimális szám: "+d);

writeln("__________");

A fenti JS program (hex2dec) folyamatábrája

Végezetül egy nagyon fontos programszerkezetet fogunk bevezetni. A fenti JavaScript program megvalósítható egy függvény létrehozásával is. Figyeljük meg, hogy így mind a hexadecimális számjegyeket kezelő függvény, mind az átváltást megvalósító program jóval egyszerűbb lett.

A program és ennek a folyamatábrája a következő:

// hexadecimális szám átalakítása decimális számmá (ver 4.0)

function hex2dec(hx) {
 if(hx=="a" || hx=="A") {
  return 10;
  }
 if(hx=="b" || hx=="B") {
  return 11;
  }
 if(hx=="c" || hx=="C") {
  return 12;
  }
 if(hx=="d" || hx=="D") {
  return 13;
  }
 if(hx=="e" || hx=="E") {
  return 14;
  }
 if(hx=="f" || hx=="F") {
  return 15;
  }
 return parseInt(hx);
 }

var x="24C";

write("Hexadecimális szám: "+x);
writeln();

var d=0;
var helyiertek=1;

var i=1;
while(i<x.length) {
 helyiertek=helyiertek*16;
 i=i+1;
 }

i=0;
while(i<x.length) {
 var sz;
 sz=hex2dec(x[i]);
 var r=sz*helyiertek;
 d=d+r;
 helyiertek=helyiertek/16;
 i=i+1;
 }

writeln("Decimális szám: "+d);

writeln("__________");

A fenti JS program (hex2dec) folyamatábrája

Jegyezzük meg, hogy a 'hex2dec' függvény létrehozható mind a korábban megismert 'switch' szerkezettel, mind egymásba ágyazott if...else... utasításokkal, például a következőképpen:

// hexadecimális szám átalakítása decimális számmá (ver 5.0)

function hex2dec(hx) {
 var sz;
 if(hx=="a" || hx=="A") {
  sz=10;
  }
 else if(hx=="b" || hx=="B") {
  sz=11;
  }
 else if(hx=="c" || hx=="C") {
  sz=12;
  }
 else if(hx=="d" || hx=="D") {
  sz=13;
  }
 else if(hx=="e" || hx=="E") {
  sz=14;
  }
 else if(hx=="f" || hx=="F") {
  sz=15;
  }
 else {
  sz=parseInt(hx);
  }
 return sz;
 }

var x="24C";

write("Hexadecimális szám: "+x);
writeln();

var d=0;
var helyiertek=1;

var i=1;
while(i<x.length) {
 helyiertek=helyiertek*16;
 i=i+1;
 }

i=0;
while(i<x.length) {
 var sz;
 sz=hex2dec(x[i]);
 var r=sz*helyiertek;
 d=d+r;
 helyiertek=helyiertek/16;
 i=i+1;
 }

writeln("Decimális szám: "+d);

writeln("__________");

Ennek a megvalósításnak az előnye, hogy a függvény bemenetét (hx) és kimenetét (sz) egyértelműen egy-egy változóval tudjuk megadni.



Példák algoritmusokra:
3. decimális szám átalakítása bináris számmá

Szótár:
– decimális számok = tízes számrendszerbeli számok
– bináris számok = kettes számrendszerbeli számok

1. egész szám átváltása

Példa: 31410 = ?2

hányados maradék
314
314:2= 157 0
157:2= 78 1
78:2= 39 0
39:2= 19 1
19:2= 9 1
9:2= 4 1
4:2= 2 0
2:2= 1 0
1:2= 0 1

Eredmény:
31410 = 1|0011|10102

Megjegyzés: mivel egy kettes számrendszerbeli szám rendszerint elég sok számjegyből áll ("hosszú"), érdemes a számjegyeket jobbról négyes csoportokra bontani.

Ellenőrzés:
1|0011|10102 = 1*28 + 1*25 + 1*24 + 1*23 + 1*21 = 256 + 32 + 16 + 8 + 2 = 31410 (ok)


A fenti algoritmust megvalósító JavaScript program:

// decimális szám átalakítása bináris számmá 

var x=314; 

writeln("Decimális szám: "+x);
writeln();

var b="";
var q=1;

while(q>0) {
 q=Math.trunc(x/2); // egész osztás!!
 write("   Hányados: "+q); 
 if(x%2==1) {
  b="1"+b;
  writeln(", maradék: "+1);
  }
 else {
  b="0"+b;
  writeln(", maradék: "+0);  
  }
 x=q;
 }

writeln();
writeln("Bináris szám: "+b);

writeln("__________");

A JS Math.trunc(...) függvénye a zárójelek között megadott valós szám egész részét adja vissza. Tehát ha két egész szám hányadosát adjuk meg a függvény argumentumaként, a Math.trunc(...) függvény értéke a tört hányadosának egész része lesz, vagyis a függvény segítségével egész osztást tudunk végezni. (Például 79=9*8+5 esetén a Math.trunc(79/8) függvény '9'-et ad vissza, a nyolccal való osztás maradékát pedig a (79%8) kifejezés segítségével kaphatjuk meg, amelynek az értéke az '5'-ös szám.)

A fenti program azonban egyszerűen megvalósítható az egész osztást lehetővé tevő Math.trunc() függvény nélkül is:

// decimális szám átalakítása bináris számmá 

var x=314; 

writeln("Decimális szám: "+x);
writeln();

var b="";
var q,m;

while(x>0) {
 if(x%2==1) {
  m="1";
  x=x-1;
  }
 else {
  m="0";
  }
 q=x/2;
 write("   Hányados: "+q); 
 writeln(", maradék: "+m);
 b=m+b;
 x=q;
 }

writeln();
writeln("Bináris szám: "+b);

writeln("__________");


A fenti JS program (bin2dec) folyamatábrája

A későbbiekben (például a pakolt BCD számábrázolás kódolásakor) szükségünk lesz egy olyan függvényre, amely egy megadott decimális számjegyet egy 4 bites kettes számrendszerbeli számmá alakít. Ehhez először alakítsuk át a fenti programot:

// decimális számjegy átalakítása 4 bites bináris számmá 

var x=3; 

writeln("Decimális számjegy: "+x);
writeln();

var b="";
var q,m;

while(x>0) {
 if(x%2==1) {
  m="1";
  x=x-1;
  }
 else {
  m="0";
  }
 q=x/2;
 b=m+b;
 x=q;
 }

var i=b.length;
while(i<4) {
 b="0"+b; // vezető 0 hozzáadása
 i=i+1;
 }

writeln("Bináris szám: "+b);

writeln("__________");

Ezután hajtsuk végre a következő lépéseket:
    (1) hozzunk létre egy 'dec2bin4' nevű függvényt a program elején, és adjuk meg zárójelek közt a függvény argumentumát szolgáltató 'x' változót, majd
    (2) a programnak azt a részét, amely az 'x' változó megadott értékéből előállítja a 'b' változóban a keresett 4 bites kettes számrendszerbeli számot, tegyük bele a 'dec2bin4' nevű függvény blokkjába, és végül
    (3) a blokk utolsó utasításának adjuk meg a 'return b;' utasítást, amely a 'dec2bin4(...)' függvény értékét adja vissza.
Így a következő programhoz jutunk:

// decimális számjegy átalakítása 4 bites bináris számmá függvény segítségével

function dec2bin4(x) { 
// függvény blokkjának kezdete

var b="";
var q,m;

while(x>0) {
 if(x%2==1) {
  m="1";
  x=x-1;
  }
 else {
  m="0";
  }
 q=x/2;
 b=m+b;
 x=q;
 }

var i=b.length;
while(i<4) {
 b="0"+b; // vezető 0 hozzáadása
 i=i+1;
 }

return b;
// függvény blokkjának vége
} 

var x=3; 

writeln("Decimális számjegy: "+x);
writeln();

writeln("Bináris szám: "+dec2bin4(x));

writeln("__________");

Figyeljük meg, hogy a függvény kipróbálásához elegendó a program végén (az ún. "főprogramban") 5 sor. A függvényt pedig innentől kezdve akárhányszor meghívhatjuk anélkül, hogy a számítás lépéseit újra és újra le kellene írnunk.


Kettő hatványai

Egy alternatív lehetőség egy decimális egész szám bináris számmá alakítására a következő:

  1. megkeressük kettőnek azt a legmagasabb hatványát, amely az átváltandó számnál kisebb vagy egyenlő;
    • a talált hatványhoz mint helyi értékhez tartozó számjegy '1' lesz;
  2. ezt kivonjuk az átváltandó számból;
  3. a kivonás eredményére (mint átváltandó számra) addig ismételjük az 1. és 2. lépéseket, ameddig a kivonás eredménye zérus nem lesz;
  4. az átváltandó szám kettes számrendszerbeli alakjában azok a számjegyek, amelyekhez nem rendeltünk '1' értéket, '0' értékűek lesznek.

Példa: 31410 = ?2

hatvány átváltandó szám/maradék számjegy
314
28=256 314−256=58 1
27=128 58<128 0
26=64 58<64 0
25=32 58−32=26 1
24=16 26−16=10 1
23=8 10−8=2 1
22=4 2<4 0
21=2 2−2=0 1
20=1 0<1 0

Eredmény:
31410 = 1|0011|10102


A fenti algoritmust megvalósító JavaScript program:

// decimális szám átalakítása bináris számmá kivonásokkal

var x=314; 

writeln("Decimális szám: "+x);
writeln();

var b="";
var helyiertek=1;

while(2*helyiertek<=x) {
 helyiertek*=2;
 }

while(helyiertek>=1) {
 if(helyiertek<=x) {
  b+="1";
  writeln("   Számjegy:    "+1);
  writeln("   Helyi érték: "+helyiertek);
  x-=helyiertek;
  }
 else {
  b+="0";
  writeln("   Számjegy:    "+0);
  writeln("   Helyi érték: "+helyiertek);
  }
 helyiertek/=2;
 }

writeln();
writeln("Bináris szám: "+b);

writeln("__________");


2. törtszám átváltása

Példa: 0.687510 = ?2

szorzat egész rész tört rész
0.6875
0.6875*2= 1.375 1 0.375
0.375*2= 0.75 0 0.75
0.75*2= 1.5 1 0.5
0.5*2= 1 1 0

Eredmény:
0.687510 = 0.10112

Megjegyzések:
(1) négynél több bináris számjegy esetén most is érdemes a számjegyeket négyes csoportokra bontani (balról, a "kettedespont" után);
(2) ha az átváltandó tízes számrendszerbeli szám egész része 0-nál nagyobb, a szám egész részét és tört részét külön-külön alakítsuk át kettes számrendszerbeli számmá.

Ellenőrzés:
0.10112 = 1*2−1 + 1*2−3 + 1*2−4 = 1/2 + 1/8 + 1/16 = 11/16 = 0.687510 (ok)


A fenti algoritmust megvalósító JavaScript program:

// tizedestört átalakítása kettedestörtté 

var x=0.6875;

writeln("A törtszám: "+x);
writeln();

var maxi=50;
var s="";

var i=1;
while(x>0 && i<=maxi) {
 x*=2;
 if(x<1) {
  write("   egész rész: 0,");
  s+="0";
  }
 else {
  write("   egész rész: 1,");
  s+="1";
  x=x-1;
  }
 writeln("   törtrész: "+x);
 if(i%4==0) {
  writeln("..... "+i+". ciklus .....");
  s+=" ";
  }
 i++;
 }

writeln();
writeln("A tört (első "+maxi+" kettedesjegy): 0."+s);

writeln("__________");


Második példa:
    (a) 0.4510 = ?2
    (b) 0.810 = ?2

Ha egy (véges) tizedestört 2-vel való szorzásakor az algoritmus által szolgáltatott bináris számjegyek szakaszos ismétlődést mutatnak, akkor kell az algoritmust befejeznünk, ha egy korábban már előfordult tört részt kapunk. Ekkor két eset lehetséges:

Oldjuk meg mindkét feladatot és ellenőrizzük a kapott eredményeket.

(a) 0.45 átalakítása kettedestörtté
szorzat egész rész tört rész megjegyzés

Eredmény:
0.4510 = 0.01110011001100...2

Megjegyzés: az algoritmus lépései során 0.80 az első olyan tört rész, amely ismétlődik, vagyis innentől a bináris számjegyek is ismétlődni fognak. Azonban 0.8 kétféleképpen kapható meg (0.90 és 0.40 kettővel való szorzásával), ezért a táblázatban a 0.80-at tartalmazó sorokban az egész rész értéke először 1, másodszor pedig 0. A bináris számjegyek ismétlődő sorozata tehát csak 0.80 után, azaz a 0.60 tört részt tartalmazó sortól kezdődik el és a 0.80 tört részt tartalmazó sorral fejeződik be (vagyis 0.8 az ismétlődő szakasz végét jelzi).

Ellenőrzés:

Vezessük be a következő változókat:
    q=0.01110011001100...
    p=4*q=1.110011001100... (a kettedespont kettővel jobbra mozog)
    r=16*p=11100.110011001100... (a kettedespont néggyel jobbra mozog)

Ekkor teljesülnek az alábbi összefüggések:
    r−p=16*p−p=15*p
valamint
    r−p=
    11100.110011001100...−1.110011001100...=
    11100−1=
    110112=2710

A fentiekből egyszerű átalakításokkal
    15*p=27 ⇒ p=27/15 és
    p=4*q ⇒ q=p/4=27/60=9/20=0.45
következik (ok).

(b) 0.8 átalakítása kettedestörtté
szorzat egész rész tört rész megjegyzés

Eredmény:
0.810 = 0.110011001100...2

Megjegyzés: az algoritmus lépései során 0.60 az első olyan tört rész, amely ismétlődik, vagyis innentől a bináris számjegyek is ismétlődni fognak. A táblázatban a 0.60 tört részt tartalmazó sorokban az egész rész értéke (1) megegyezik. A bináris számjegyek ismétlődő sorozata tehát a 0.60 tört részt tartalmazó sortól kezdődik el és a 0.80 tört részt tartalmazó sorral fejeződik be.

Ellenőrzés:

Vezessük be a következő változókat:
    q=0.110011001100...
    r=16*q=1100.110011001100... (a kettedespont néggyel jobbra mozog)

Ekkor teljesülnek az alábbi összefüggések:
    r−q=16*q−q=15*q
valamint
    r−q=
    1100.110011001100...−0.110011001100...=
    11002=1210

A fentiekből egyszerű átalakításokkal
    15*q=12 ⇒ q=12/15=4/5=0.8
következik (ok).

Mivel a végtelen tizedestörtek szorzását a számítógép véges számú biten hajtja végre, ezért szorzáskor a szorzat közelítő értékét kapjuk meg. Ezért érdemes a végtelen szakaszos tizedestörteket először racionális törtekké alakítani, és utána átváltani őket kettedestörtekké (ld. a következő példát).


Harmadik példa: 5/7=0.714285714285...10 = ?2

Egy végtelen szakaszos tizedestört (q) átváltásakor először keressük meg a tizedestörtet előállító racionális törtszámot (q=a/b, ahol a,b∈ℤ, b≠0).

szorzat egész rész (b) tört rész (x/y) x/y

Eredmény:
5/710 = 0.101101101...2

Ha adott egy q=a/b (b≠0) alakú racionális törtszám, a fenti algoritmus egész számok szorzásával is elvégezhető. Az egyszerűség kedvéért tegyük fel, hogy 0<q<1, és a tört számlálója és nevezője pozitív természetes számok (amelyekre 0<a<b teljesül).

Az előző algoritmust módosítsuk a következőképpen:

  1. legyen x=a és y=b
    (az átváltandó tört a/b; kezdetben x/y=a/b, majd a további lépésekben x/y-t szorozzuk 2-vel, és x-et úgy módosítjuk, hogy x/y mindig a szorzat tört részét adja meg)
  2. ha 2*x<y, akkor
    • legyen b=0 és írassuk ki 'b'-t
      (ha 2*x/y<1, akkor 2-vel szorozva az x/y törtet, az egész rész 0 lesz)
    • legyen x=2*x
      (ha 2*x/y<1, akkor 2-vel szorozva az x/y törtet, a tört rész számlálója 2*x lesz)
  3. ha 2*x≥y, akkor
    • legyen b=1 és írassuk ki 'b'-t
      (ha 2*x/y≥1, akkor 2-vel szorozva az x/y törtet, az egész rész 1 lesz)
    • legyen x=2*x−y
      (ha 2*x/y≥1, akkor 2-vel szorozva az x/y törtet, a tört rész számlálója 2*x−y lesz, mivel 2*x/y−1=2*x/y−y/y=(2*x−y)/y teljesül)
  4. ha x==0 vagy az x/y tört rész megegyezik egy korábbi értékkel, akkor ugrás a 6. lépésre
    (ha x==0, akkor véges kettedestörtet kaptunk; ha az x/y tört rész (ill. ennek 'x' számlálója) korábban már előfordult, akkor innentől az egész részek eddig kapott sorozata végtelen sokszor ismétlődni fog, azaz végtelen szakaszos kettedestörtet kaptunk)
  5. ugrás a 2. lépésre
  6. algoritmus vége

Nézzük meg, hogyan hajtható végre az algoritmus, ha a q=5/7 racionális törtszámot alakítjuk át kettedestörtté.

5/7 átváltása szorzat tört rész egész rész megjegyzés
2*5= 10 10-7=3 1
2*3= 6 6 0
2*6= 12 12-7=5 1
2*5= 10 10-7=3 1 (innentől ismétlődik)
...

Az eredmény:
5/710 = 0.101101101...2

Ellenőrzés:

Vezessük be a következő változókat:
    p=0.101101101...
    r=8*p=101.101101101... (a kettedespont három pozícióval jobbra mozog)

Ekkor teljesülnek az alábbi összefüggések:
    r−p=8*p−p=7*p
valamint
    r−p=
    101.101101101...−0.101101101...=
    101−0=
    1012=510

A fentiekből egyszerű átalakításokkal
    7*p=5 ⇒ p=5/7
következik (ok).


A fenti algoritmust megvalósító JavaScript program (első, egyszerűbb változat):

// racionális törtszám átalakítása kettedestörtté (1. verzió)

/* feltétel: az átalakítandó törtszám pozitív és 1-nél kisebb (azaz x<y teljesül) */

var x=5, y=7;

writeln("A törtszám: "+x+"/"+y);
writeln();

var maxi=50;
var s="";

var i=1;
while(x>0 && i<=maxi) {
 if(2*x<y) {
  write("   egész rész: 0,");
  s+="0";
  x=2*x;
  }
 else {
  write("   egész rész: 1,");
  s+="1";
  x=2*x-y;
  }
 writeln("   törtrész: "+x+"/"+y);
 if(i%4==0) {
  writeln("..... "+i+". ciklus .....");
  s+=" ";
  }
 i++;
 }

writeln();
writeln("A tört (első "+maxi+" kettedesjegy): 0."+s);

writeln("__________");

A fenti algoritmust megvalósító JavaScript program (második, teljes változat; kiegészítő anyag):

// racionális törtszám átalakítása kettedestörtté (második verzió)

/* feltétel: az átalakítandó törtszám pozitív és 1-nél kisebb */

var vereme=[];
var veremt=[];

function betesz(b,x) {
 var n=vereme.length; // ennyi elem van a veremben
 vereme[n]=b;
 veremt[n]=x;
 }

function beteszjelolot(index,s1,s2) {
 for(var k=index;k<vereme.length;k++) {
  vereme[vereme.length-k]=vereme[vereme.length-k-1];
  veremt[veremt.length-k]=veremt[veremt.length-k-1];
  }
 vereme[index]=s1;
 veremt[index]=s1;
 vereme[vereme.length]=s2;
 veremt[veremt.length]=s2;
 }

function keres(x) {
 var index=-1;
 for(var k=0;k<veremt.length;k++) {
  if(veremt[k]==x) {
   index=k;
   break;
   }
  }
 return index;
 }

function kivesze(index) {
 if(0>index || index>=vereme.length) return -1;
 return vereme[index];
 }

function kiveszt(index) {
 if(0>index || index>=veremt.length) return -1;
 return veremt[index];
 }

function kiveszmindet() {
 var s="";
 for(var k=0;k<vereme.length;k++) {
  s+=vereme[k];
  }
 return s;
 }

/*************************************
 törtszám megadása (feltétel: x<y) 
**************************************/

// var x=1, y=2;
var x=5, y=7;
// var x=9, y=14;
// var x=9, y=20;
// var x=5, y=14;
// var x=706, y=990;

writeln("A törtszám: "+x+"/"+y);
writeln();

var maxi=100;
var s="";
var jel1="{";
var jel2="}...";

var i=1;
while(x>0 && i<=maxi) {
 var b;
 if(2*x<y) {
  b=0;
  x=2*x;
  }
 else {
  b=1;
  x=2*x-y;
  }

 write("   egész rész: "+b+",");
 writeln("   törtrész: "+x+"/"+y);

 var index=keres(x);
 if(index>=0) {
  writeln("   ** ismétlődés **");
  write("   korábbi egész rész: "+kivesze(index)+",");
  writeln("   korábbi törtrész: "+kiveszt(index)+"/"+y);
  if(b==kivesze(index)) {
   writeln("   [ismétlődő szakasz kezdete]");
   writeln("   [ismétlődő szakasz hossza: "+(i-index));
   beteszjelolot(index,jel1,jel2);
   }
  else {
   writeln("   [ismétlődő szakasz vége]");
   betesz(b,x); // ezt még betesszük a verembe
   beteszjelolot(index+1,jel1,jel2);
   }
  break;
  }

 betesz(b,x);

 if(i%4==0) {
  writeln("..... "+i+". ciklus .....");
  }

 i++;
 }

s=kiveszmindet();

writeln();
writeln("A tört értéke (első max. "+maxi+" kettedesjegy): 0."+s);

writeln("__________");



Példák algoritmusokra:
4. bináris szám átalakítása hexadecimális számmá

Szótár:
– bináris számok = kettes számrendszerbeli számok
– hexadecimális számok = tizenhatos számrendszerbeli számok

1. egész szám átváltása

Példa: 1010|11012 = ?16

Két fontos dolgot tudnunk kell az algoritmus megértéséhez:

(1) Mivel a kettes számrendszerbeli (egész) számok rendszerint elég sok számjegyből állnak, érdemes a bináris számjegyeket jobbról négyes csoportokra osztani (az utolsó csoportot pedig balról kiegészíteni "vezető" nullákkal).

Például ha a 1010010110 bináris szám számjegyeit jobbról négyes csoportokra bontjuk, akkor
    0010|1001|0110
adódik.

(2) A hexadecimális számok számjegyei a decimális számjegyek (0, 1, ..., 9) mellett az A, B, C, D, E és F számjegyeket is magukba foglalják.

Hexadecimális számjegyek

A bináris egész számokat hexadecimális számokká alakító algoritmus lépései:

Eredmény: 1010|11012 = AD16


A fenti példa táblázatos formában:

1010|11012 = ?16

bin
számjegy
helyi érték szorzat hexa
számjegy
1 23=8 8
0 22=4 0
1 21=2 2
0 20=1 0
összesen 10 A
1 23=8 8
1 22=4 4
0 21=2 0
1 20=1 1
összesen 13 D

Eredmény:
1010|11012 = AD16

Ellenőrzés:
    (1) 1010|11012 = 1*27 + 0*26 + 1*25 + 0*24 + 1*23 + 1*22 + 0*21 + 1*20 = 128 + 32 + 8 + 4 + 1 = 17310 (ld. 2. algoritmus)
    (2) AD16 = 10*161 + 13*160 = 10*16 + 13*1 = 160 + 13 = 17310 (ld. 3. algoritmus)
A két szám megegyezik (ok).


A fenti algoritmust megvalósító JavaScript program:

// bináris szám átalakítása hexadecimális számmá 

function dec2hex(sz) {
 var hx="-1";
 switch(sz) {
  case 10: hx="A"; break;
  case 11: hx="B"; break;
  case 12: hx="C"; break;
  case 13: hx="D"; break;
  case 14: hx="E"; break;
  case 15: hx="F"; break;
  default: 
   hx=""+sz;  
  }
 return hx;
 }

var x="10101101";
while(x.length%4!=0) {
 x="0"+x; // vezető 0-k beírása
 }

var k=x.length-1;
var t=""; // végeredmény

var s="";
var h=0;
var helyiertek=1;

for(var i=0;i<x.length;i++) {
 s=x[k]+s;
 if(x[k]==1) {
  h+=helyiertek;
  }
 helyiertek*=2;
 k--;
 if(i%4==3) {
  writeln("    "+s+" = "+h+" = "+dec2hex(h));
  t=dec2hex(h)+t;
  writeln(" ");
  s="";
  h=0;
  helyiertek=1;
  }
 }

writeln(x+" = "+t);


writeln("____________"); 


A fordított irányú átváltás, azaz egy hexadecimális szám átváltása bináris számmá az előző algoritmushoz teljesen hasonlóan működik. Vegyünk egy tetszőleges hexadecimális számot, és

Példa: 2AD16 = ?2

Tehát az eredmény: 2AD16 = 0010|1010|10112


Az algoritmust megvalósító JavaScript program:

// hexadecimális szám átalakítása bináris számmá 

function hex2dec(hx) {
 var sz=-1;
 switch(hx) {
  case "a":
  case "A": sz=10; break;
  case "b":
  case "B": sz=11; break;
  case "c":
  case "C": sz=12; break;
  case "d":
  case "D": sz=13; break;
  case "e":
  case "E": sz=14; break;
  case "f":
  case "F": sz=15; break;
  default: 
   sz=parseInt(hx);  
  }
 return sz;
 }

var x="2AD";

writeln("A hexadecimális szám: "+x);
writeln();

var t=""; // végeredmény

for(var i=0;i<x.length;i++) {
 var h=hex2dec(x[i]);
 var helyiertek=8;
 var s=""; // részeredmény

 while(helyiertek>=1) {
  if(h>=helyiertek) {
   s=s+"1";
   h-=helyiertek;
   }
  else {
   s=s+"0";
   }
  helyiertek/=2;
  }

 writeln("    "+x[i]+" = "+hex2dec(x[i])+" = "+s);
 if(i>0) {
  t=t+" ";
  }
 t=t+s;
 }

writeln();
writeln(x+" bináris alakja: "+t);

writeln("____________"); 


2. törtszám átváltása

Példa: 0.1011|01012 = ?16

Mivel a kettes számrendszerbeli (tört) számok rendszerint elég sok számjegyből állnak, érdemes a bináris számjegyeket balról (0. után kezdődően) négyes csoportokra osztani (az utolsó csoportot pedig jobbról kiegészíteni "vezető" nullákkal).

Például ha a 0.10110101 bináris szám számjegyeit balról négyes csoportokra bontjuk, akkor
    0.1011|0101
adódik.

A bináris törtszámokat hexadecimális számokká alakító algoritmus lépései:

Eredmény: 0.1011|01012 = 0.B516


A fenti példa táblázatos formában:

0.1011|01012 = ?16

bin
számjegy
helyi érték szorzat hexa
számjegy
1 23=8 8
0 22=4 0
1 21=2 2
1 20=1 1
összesen 11 B
0 23=8 0
1 22=4 4
0 21=2 0
1 20=1 1
összesen 5 5

Eredmény:
0.1011|01012 = 0.B516

Ellenőrzés:
    (1) 0.1011|01012 = 1*2−1 + 1*2−3 + 1*2−4 + 1*2−6 + 1*2−8 = 1/2 + 1/8 + 1/16 + 1/64 + 1/256 = 128/256 + 32/256 + 16/256 + 4/256 + 1/256 = 181/256 = 0.7070312510
    (2) 0.B516 = 11*16−1 + 5*16−2 = 11/16 + 5/256 = 176/256 + 5/256 = 181/256 = 0.7070312510
A két szám megegyezik (ok).



Példák algoritmusokra:
5. decimális szám átalakítása hexadecimális számmá

Szótár:
– decimális számok = tízes számrendszerbeli számok
– hexadecimális számok = tizenhatos számrendszerbeli számok

Példa: 31410 = ?16

1. lépés

hányados maradék
314
314:2= 157 0
157:2= 78 1
78:2= 39 0
39:2= 19 1
19:2= 9 1
9:2= 4 1
4:2= 2 0
2:2= 1 0
1:2= 0 1

Tehát 31410 = 1|0011|10102 → 0001|0011|10102

2. lépés

bin
számjegy
helyi érték szorzat hexa
számjegy
0 23=8 0
0 22=4 0
0 21=2 0
1 20=1 1
összesen 1 1
0 23=8 0
0 22=4 0
1 21=2 2
1 20=1 1
összesen 3 3
1 23=8 8
0 22=4 0
1 21=2 2
0 20=1 0
összesen 10 A

Tehát 1|0011|10102 = 13A16

Eredmény:
31410 = 13A16

Ellenőrzés:
13A16 = 1*162 + 3*161 + 10*160 = 1*16*16 + 3*16 + 10*1 = 256 + 48 + 10 = 31410 (ok)


Egy decimális számot a következő algoritmussal egy lépésben is átalakíthatjuk hexadecimális számmá:

hányados maradék ellenőrzés
314
314:16= 19 10=A 314=16*19+10
19:16= 1 3 19=16*1+3
1:16= 0 1 1=16*0+1

Eredmény:
31410 = 13A16


A fenti algoritmust megvalósító JavaScript program:

// decimális szám átalakítása hexadecimális számmá osztással

function hex2dec(hx) {
 var sz=-1;
 switch(hx) {
  case "a":
  case "A": sz=10; break;
  case "b":
  case "B": sz=11; break;
  case "c":
  case "C": sz=12; break;
  case "d":
  case "D": sz=13; break;
  case "e":
  case "E": sz=14; break;
  case "f":
  case "F": sz=15; break;
  default: 
   sz=parseInt(hx);  
  }
 return sz;
 }

function dec2hex(sz) {
 var hx="-1";
 switch(sz) {
  case 10: hx="A"; break;
  case 11: hx="B"; break;
  case 12: hx="C"; break;
  case 13: hx="D"; break;
  case 14: hx="E"; break;
  case 15: hx="F"; break;
  default: 
   hx=""+sz;  
  }
 return hx;
 }

var x="314"; 

writeln("Decimális szám: "+x);
writeln();

var h="";
var q=1;

while(q>0) {
 q=Math.trunc(x/16); // egész osztás!!
 write("   Hányados: "+q); 
 var m=x-16*q;
 writeln(", maradék: "+m);
 h=dec2hex(m)+h;
 x=q;
 }

writeln();
writeln("Hexadecimális szám: "+h);

writeln("__________");


16 hatványai

Egy további lehetőség egy decimális szám hexadecimális számmá alakítására a következő:

Példa: 152610 = ?2

hatvány átváltandó szám/maradék kivonások száma
1526
162=256 1526−256=1270>256 1
1270−256=1014>256 2
1014−256=758>256 3
758−256=502>256 4
502−256=246<256 5
161=16 246−16=230>16 1
230−16=214>16 2
214−16=198>16 3
198−16=182>16 4
182−16=166>16 5
166−16=150>16 6
150−16=134>16 7
134−16=118>16 8
118−16=102>16 9
102−16=86>16 10
86−16=70>16 11
70−16=54>16 12
54−16=38>16 13
38−16=22>16 14
22−16=6<16 15=F
160=1 6−1=5>1 1
5−1=4>1 2
4−1=3>1 3
3−1=2>1 4
2−1=1≥1 5
1−1=0<1 6

Eredmény:
5F616 = 5*162 + F*161 + 6*160 = 5*256 + 15*16 + 6 = 152610


A fenti algoritmust megvalósító JavaScript program:

// decimális szám átalakítása hexadecimális számmá kivonásokkal

function hex2dec(hx) {
 var sz=-1;
 switch(hx) {
  case "a":
  case "A": sz=10; break;
  case "b":
  case "B": sz=11; break;
  case "c":
  case "C": sz=12; break;
  case "d":
  case "D": sz=13; break;
  case "e":
  case "E": sz=14; break;
  case "f":
  case "F": sz=15; break;
  default: 
   sz=parseInt(hx);  
  }
 return sz;
 }

function dec2hex(sz) {
 var hx="-1";
 switch(sz) {
  case 10: hx="A"; break;
  case 11: hx="B"; break;
  case 12: hx="C"; break;
  case 13: hx="D"; break;
  case 14: hx="E"; break;
  case 15: hx="F"; break;
  default: 
   hx=""+sz;  
  }
 return hx;
 }

var x=1526; 

writeln("Decimális szám: "+x);
writeln();

var h="";
var helyiertek=1;

while(16*helyiertek<=x) {
 helyiertek*=16;
 }

while(helyiertek>=1) {
 if(helyiertek<=x) {
  var sz=0;
  while(helyiertek<=x) {
   sz++;
   x-=helyiertek;
   }
  h+=dec2hex(sz);
  writeln("   Számjegy:    "+dec2hex(sz));
  writeln("   Helyi érték: "+helyiertek);
  }
 else {
  h+="0";
  writeln("   Számjegy:    "+0);
  writeln("   Helyi érték: "+helyiertek);
  }
 helyiertek/=16;
 }

writeln();
writeln("Hexadecimális szám: "+h);

writeln("__________");



Példák algoritmusokra:
6. végtelen szakaszos tizedes tört átalakítása racionális törtszámmá

A végtelen tizedes törtek szakaszosak, ha a tizedespont (.) után egy adott helyiértéktől kezdődően azonos számjegycsoportok ismétlődnek (végtelen sokszor). Az ismétlődő számjegycsoportokat a továbbiakban aláhúzással jelöljük.
Például 12.8333333... esetén az ismétlődő számjegycsoport egy számjegyből áll (3); 0.538461538461538461... esetén pedig az ismétlődő számjegycsoport hat számjegyből áll (538461).

Minden racionális törtszám felírható véges vagy végtelen szakaszos tizedes tört alakban.

Feladat:

Egy 'q' végtelen szakaszos tizedes tört esetében határozzuk meg azt az a/b racionális törtszámot (a,b∈ℤ, b≠0), amelyre q=a/b teljesül.

Példák:
ha q=0.666666..., akkor a/b=2/3, mivel 2/3≈0.666666...
ha q=0.8333333..., akkor a/b=5/6, mivel 5/6≈0.8333333...
ha q=12.8333333..., akkor a/b=77/6, mivel 12=72/6 és 5/6≈0.8333333...
ha q=0.538461538461538461..., akkor a/b=7/13, mivel 7/13≈0.538461538461538461...

Korábban láttuk, hogy a végtelen szakaszos kettedestörtek is felírhatók racionális törtszámként:
ha q=0.0111001100...2, akkor a/b=9/20 (lásd 0.45 átalakítását kettedestörtté)
ha q=0.11001100...2, akkor a/b=4/5 (lásd 0.8 átalakítását kettedestörtté)
ha q=0.101101...2, akkor a/b=9/20 (lásd 5/7 átalakítását kettedestörtté)

A feladat általános megoldása:

Egy végtelen szakaszos tizedestörtet egy egyszerű algoritmus segítségével mindig elő tudunk állítani a/b (a,b∈ℤ, b≠0) alakú racionális törtszámként.

Az algoritmusban a végtelen szakaszos tizedes törteknek három fontos tulajdonságát használjuk ki. Az algoritmus vázlatos leírása a következő:
(1) Legyen 'q' végtelen szakaszos tizedes tört (az egyszerűség kedvéért tegyük fel, hogy 1>q>0). Ha 'q'-t "felszorozzuk" 10 megfelelő hatványával (10n), akkor elérhető, hogy az ismétlődő szakaszok közvetlenül a tizedespont után kezdődjenek:
    p=q*10n
Ekkor 'p' egész részét pontosan azok a számjegyek alkotják, amelyek 'q'-ban közvetlenül a tizedespont után és az ismétlődő szakaszok kezdete előtt állnak (ha nincsenek ilyen számjegyek, azaz n=0, akkor 'p' egész része 0 és p=q teljesül).
(2) Mivel a 'p' törtben az ismétlődő szakaszok közvetlenül a tizedespont után kezdődnek, ezért a törtet "felszorozva" 10 megfelelő hatványával (10m) mindig elérhető, hogy pontosan egy szakasz a tizedespont elé kerüljön:
    r=p*10m=q*10n+m
Ekkor 'r' egész részét úgy kapjuk meg, hogy vesszük azokat a számjegyeket, amelyek 'q'-ban közvetlenül a tizedespont után állnak, és hozzávesszük ezekhez egy ismétlődő szakasz számjegyeit.
(3) a 'p' törtben és az 'r' törtben az ismétlődő szakaszok megegyeznek és közvetlenül a tizedespont után kezdődnek; ezért a 'p' és 'r' törtek tizedespont utáni része megegyezik, vagyis az (r−p) különbség egész szám lesz (a törtrész zérus lesz):
    r−p=[r]−[p] (ahol [r] és [p] az 'r' és 'p' törtszámok egész részét jelöli).
A 'p' végtelen szakaszos tizedes tört a fentiek alapján a következőképpen fejezhető ki két egész szám hányadosaként:
    r−p=p*10m−p=p*(10m−1) ⇒ p=(r−p)/(10m−1)
vagyis
    p=([r]−[p])/(10m−1)
ahol 'm' az ismétlődő szakasz hossza.
(4) Ezek után 'q'-t is könnyen meghatározhatjuk:
    q=p/10n.
ahol 'n' azoknak a számjegyeknek a száma, amelyek a 'q' szám tört részében az ismétlődő szakasz kezdete előtt helyezkednek el. (Korábban már láttuk, hogy ha az ismétlődő szakaszok közvetlenül a tizedespont után kezdődnek, akkor n=0 miatt q=p teljesül.)
A fenti képletekből egyszerű behelyettesítéssel adódik, hogy ha 'q'-t egyszer 10n+m-mel, majd 10n-nel szorozzuk, akkor a 'q' előállítását racionális törtszámként közvetlenül is megkaphatjuk:
    q=([q*10n+m]−[q*10n])/(10n+m−10n)
A fenti képletben 'n' azoknak a tizedesjegyeknek a száma, amelyek a 'q' szám tört részében az ismétlődő szakasz kezdete előtt helyezkednek el és 'm' az ismétlődő szakasz hossza.

(1) Például tekintsük a q=0.666666... végtelen szakaszos tizedes törtet, amelyben az ismétlődő szakaszok közvetlenül a tizedespont után kezdődnek (n=0). Szorozzuk be q-t 10-zel (m=1), majd vonjuk ki q-t a kapott szorzatból, hogy eltűnjenek a tizedesjegyek:
10*q=6.666666...
10*q−q=6.666666...−0.666666...=6
Ebből már egyszerű átalakítással
9*q=6 ⇒ q=6/9=2/3
adódik, ami éppen a keresett alak.

(2) Egy másik példaként tekintsük a q=0.8333333... végtelen szakaszos tizedes törtet. Szorozzuk be q-t 100-zal (n+m=2), majd 10-zel (n=1), és vonjuk ki a kapott szorzatokat egymásból, hogy eltűnjenek a tizedesjegyek:
100*q=83.333333...
10*q=8.3333333...
100*q−10*q=83.333333...−8.3333333...=83−8=75
Ebből már egyszerű átalakítással
90*q=75 ⇒ q=75/90=5/6
adódik, ami éppen a keresett alak.

(3) Utolsó példaként tekintsük a q=0.538461538461538... végtelen szakaszos tizedes törtet, amelyben az ismétlődő szakaszok közvetlenül a tizedespont után kezdődnek (n=0). Szorozzuk be q-t 106-nal (ahol m=6 az ismétlődő szakasz hossza!), és vonjuk ki q-t a kapott szorzatból, hogy eltűnjenek a tizedesjegyek:
106*q=538461.538461538461538...
106*q−q=538461.538461538461538...−0.538461538461538...=538461
Ebből már egyszerű átalakítással
(106−1)*q=538461 ⇒ q=538461/999999=7/13
adódik, ami éppen a keresett alak. (Megjegyzés: mivel lnko(538461,999999)=76923, ezzel egyszerűsíthetjük a törtet: 538461/76923=7 és 999999/76923=13 miatt a fenti eredmény adódik.)

A fenti algoritmus általánosítható bármilyen számrendszerben ábrázolt végtelen szakaszos (kettedes, harmados, negyedes stb.) törtszámokra. Például végtelen szakaszos kettedestörtek esetén azt használjuk ki, hogy
– a törtszámot 2-vel szorozva a kettedespontot egy hellyel jobbra mozgathatjuk,
– a törtszámot 4=22-vel szorozva a kettedespontot két hellyel jobbra mozgathatjuk,
– a törtszámot 8=23-cal szorozva a kettedespontot 3 hellyel jobbra mozgathatjuk,
...
– a törtszámot 2n-nel szorozva a kettedespontot 'n' hellyel jobbra mozgathatjuk.

(4) Például tekintsük a q=0.101101101... végtelen szakaszos kettedes törtet, amelyben az ismétlődő szakaszok közvetlenül a tizedespont után kezdődnek (n=0). Szorozzuk be q-t 8=23-cal (m=3), majd vonjuk ki q-t a kapott szorzatból, hogy eltűnjenek a tizedesjegyek:
8*q=101.101101101...
8*q−q=101.101101101...−0.101101101...=1012=510
Ebből már egyszerű átalakítással
7*q=5 ⇒ q=5/7
adódik. Erről a racionális törtszámról azonban korábban már beláttuk, hogy kettedes törtként éppen a fenti alakú.

Egy fontos kiegészítés:

Bármely véges tizedes tört felírható úgy, hogy az utolsó tizedesjegyét 1-gyel csökkentjük, és utána csupa 9-esből álló végtelen számsorozatot írunk (Pappné Ádám 1996: 95).
Például alakítsuk racionális törtszámmá a q=0.99999... végtelen szakaszos tizedes törtet. A korábbi algoritmust használva 10*q=9.99999... miatt fennáll a 10*q−q=9 összefüggés. Másrészt 10*q−q=9*q nyilvánvalóan teljesül. A két összefüggésből 9*q=9 teljesül, amiből q=1 következik.

A fenti összefüggés bármely számrendszerre megfogalmazható, azonban kettedestörtek esetén 9 helyett 1, tizenhatodos törtek esetén pedig 9 helyett F értendő. Ezért azokat a végtelen szakaszos tizedestörteket, amelyekben a legnagyobb értékű számjegy végtelen sokszor szakaszosan ismétlődik, a továbbiakban nem használjuk. Ennek megfelelően


A fenti algoritmust megvalósító JavaScript program:

// végtelen szakaszos tizedestört átalakítása racionális törtszámmá (lépésenként)

/* feltétel: a szám 
   0.xy... 
alakú, ahol 
'x' az ismétlődő szakasz előtti számjegyeket,
'y' az ismétlődő szakasz számjegyeit (legalább egy van)
tartalmazza */ 

function hatvany(x,n) {
/* feltétel: n pozitív egész szám */
 var q=1; 
 for(var i=1;i<=n;i++) {
  q*=x;
  }
 return q;
 }

var x="", y="6";
// var x="8", y="3";
// var x="", y="538461";

writeln("A törtszám: 0."+x+y+y+y+"...");
writeln();

var n=x.length;;
var m=y.length;

var pe=0;
if(n>0) {
 pe=Number(x);
 }

var pa=Number(x+y)-pe;
var pb=hatvany(10,m)-1;

var a=pa;
var b=pb*hatvany(10,n);

writeln("A racionális törtszám: "+a+"/"+b);

writeln("__________");


A fenti algoritmust a korábban megadott képlet alkalmazásával is megvalósíthatjuk egy JavaScript program segítségével:

// végtelen szakaszos tizedestört átalakítása racionális törtszámmá (képlettel)

/* feltétel: a szám 
   0.xy... 
alakú, ahol 
'x' az ismétlődő szakasz előtti számjegyeket,
'y' az ismétlődő szakasz számjegyeit (legalább egy van)
tartalmazza */ 

function hatvany(x,n) {
/* feltétel: n pozitív egész szám */
 var q=1; 
 for(var i=1;i<=n;i++) {
  q*=x;
  }
 return q;
 }

// var x="", y="6";
// var x="8", y="3";
var x="", y="538461";

writeln("A törtszám: 0."+x+y+y+y+"...");
writeln();

var a=Number(x+y);
if(x.length>0) {
 a=a-Number(x);
 }

var n=x.length;;
var m=y.length;

var b=hatvany(10,n+m)-hatvany(10,n);

writeln("A racionális törtszám: "+a+"/"+b);

writeln("__________");



Példák algoritmusokra:
7. két egész szám legnagyobb közös osztójának meghatározása (euklideszi algoritmus)

Amikor egy végtelen szakaszos tizedes törtet racionális törtszámmá alakítunk, hosszú ismétlődő szakaszok esetén könnyen előfordulhat, hogy az algoritmus végén olyan törtet kapunk, amelynek mind a számlálója, mind a nevezője viszonylag nagy abszolút értékű egész szám. Ilyenkor célszerű a törtet a lehető legjobban leegyszerűsíteni, azaz a tört alapalakját meghatározni (amikor a számláló és a nevező relatív primek, azaz legnagyobb közös osztójuk 1). (Például az előző szakasz harmadik példájában a 'q' végtelen szakaszos tizedes törtre, amely m=6 hosszúságú ismétlődő szakaszokat tartalmazott, a q=538461/999999 racionális törtszámot kaptuk.)

Az a/b racionális törtszám (a,b∈ℤ, b≠0) alapalakját úgy kaphatjuk meg, hogy először meghatározzuk az 'a' és 'b' egész számok legnagyobb közös osztóját, majd ezzel egyszerűsítjük a törtet.

Feladat:

Határozzuk meg a 'a' és 'b' egész számok (a,b∈ℤ) legnagyobb közös osztóját. Az egyszerűség kedvéért tételezzük fel, hogy 'a' és 'b' pozitív természetes számok, amelyekre a≥b teljesül.

  1. legyen x=a és y=b
  2. osszuk el az 'x' számot maradékosan 'y'-nal , és legyen
    x=y*q+r
    ahol az 'r' maradékra 0≤r<y teljesül
  3. ha r==0, ugorjunk az 5. lépésre
  4. legyen x=y és y=r, és folytassuk az algoritmust a 2. lépéssel
  5. az 'a' és 'b' számok legnagyobb közös osztója
    lnko(a,b)=y
  6. az algoritmus befejeződött

Például határozzuk meg az euklideszi algoritmus alapján az a=999999 és b=538461 számok legnagyobb közös osztóját. Ekkor az algoritmus lépései a következők:

Osszuk el a tört számlálóját és nevezőjét a megtalált legnagyobb közös osztóval. Mivel
    999999/76923=13 és
    538461/76923=7,
ezért
    999999/538461=13/7
teljesül. Az a/b=999999/538461 tört alapalakja tehát a/b=13/7. (Megjegyzés: az előző szakasz harmadik példájában a fenti tört reciproka szerepelt, amelyre nyilvánvalóan 538461/999999=7/13 teljesül.)


A fenti algoritmust megvalósító JavaScript program:

// két szám legnagyobb közös osztójának meghatározása (euklideszi algoritmus) 

/* feltétel: a>b>0 teljesül */

function egesz_osztas(x,y) {
/* x és y nemnegatív egész számok */
 var q=0;
 if(y<=0 || x<0) return "NaN";
 while(x>=y) {
  x-=y;
  q++;
  }
 return q;
 }

var a=999999, b=538461;

writeln("A két szám: a="+a+", b="+b);
writeln();

var x=a, y=b;
var q, r=1;

while(true) {
 q=egesz_osztas(x,y);
 // q=Math.trunc(x/y);
 r=x-y*q;

 if(r==0) {
  break;
  }

 x=y;
 y=r;
 }

writeln("A legnagyobb közös osztó: "+y);

writeln("__________");




Tartalom
Boda István, 2023.