Positional number systems
In digital computers, data is generally represented as a sequence of binary digits, e.g. in the form of binary numbers. Since binary numbers are difficult to handle, we usually display them in the hexadecimal number system (i.e. in the positional number system with base 16) as hexadecimal numbers.
A number system (or number representation system) defines uniform rules which determine how we represent numbers by a series of digits.
- The base of a number system is a natural number that is greater than 1 (for example, 2, 10, or 16). Based on this, we speak, for example, of binary, decimal or hexadecimal number systems or notations.
- The idea of positional number systems is based on the concept of digits and their positional value.
For example,
- in the binary number system, the set of digits is {0, 1}, and the positional values of digits are the powers of 2 whose exponents are natural numbers starting with 0;⇒
- the digits of the binary number system are called bits
- in the decimal number system, the set of digits is {0, 1, 2, ..., 9}, and the positional values of digits are the powers of 10 whose exponents are natural numbers starting with 0;
- in the hexadecimal number system, the set of digits is {0, 1, 2, ..., 9, A, B, ..., F}, and the positional values of digits are the powers of 16 whose exponents are natural numbers starting with 0.⇒ (Note that the digits A, B, ..., F correspond to the numbers 10, 11, ..., 15 in the decimal number system, respectively.⇒)
- In a positional number system, a given number is represented as a sequence of digits.
- In the case of non-integer (rational, real) numbers, a dot ('.') separates the integer and the fractional parts of the numbers.
- The value of a number is obtained by multiplying the value of each digit by its positional value and adding the resulting products. Performing the operations in the decimal number system, the final result of the addition will give the value of the number in decimal notation.
- For example, in the decimal number system, from right to left,
– the first positional value is 100=1 and so the corresponding digit represents the number of ones,
– the second positional value is 101=10 and so the corresponding digit represents the number of tens,
– the third positional value is 102=100 and so the corresponding digit represents the number of hundreds etc.In general, numbers in a number system with base 'b' can be described or represented by the following formula:
Examples:
(1) a real number in the decimal number system (b=10):
314.610 = 3*102+1*101+4*100 + 6*10−1(2) an integer in the binary number system (b=2):
1010112 = 1*25+1*23+1*21+1*20 = 4310(3) a real number in the binary number system (b=2):
101011.1012 = 1*25+1*23+1*21+1*20 + 1*2−1+1*2−3 = 43.62510(4) an integer in the hexadecimal number system (b=16):
1C416 = 1*162+12*161+4*160 = 45210(5) a real number in the hexadecimal number system (b=16):
1C4.416 = 1*162+12*161+4*160 + 4*16−1 = 452.2510
Examples of algorithms
In computer science, or in general, in the ubiquitous and rapidly evolving information and communication technology (IKT), the concept of algorithm is fundamental.
An algorithm is a prescribed set of well-defined instructions or statements for the solution of a given problem (or a group of similar problems), in a finite number of steps executed in a given order (e.g. the performance of a calculation).The algorithms that are important to us are those that can be described ("encoded") with the help of a computer program. In that case, we correspond to statements or instructions that perform specific actions or operations for each step of the algorithm.
We will provide a number of programs for the formal description of the algorithms described in this chapter. The most important components of these programs are reviewed below.
The examples here are given in the JavaScript programming language. To get to know the language more thoroughly, it is strongly recommended to study the following materials which are ideal for self-study:
JavaScript Tutorial (2022-09-27)
JavaScript Algorithms and Data Structures (2022-10-02)
The simplest programs are built from the following statements:
- the declaration statements which are used to create variables; variables are the most important components of programs that have a unique name and can store different types of values; for example
- var n; // declaration of the variable named 'n'
- var i=1; // declaration of the variable named 'i' by assigning the initial value 1 to it
- the assingment statements which are used to change the stored value of the given variables; they usually store the result of one or more operations in a variable; for example
- i=i+1; /* adding 1 to the current value of the variable named 'i' and storing the result of the operation in the same variable (i.e. in the variable 'i'); the previous value of 'i' will be deleted */
- circumference=2*r*3.14; /* multiplying the variable called 'r' first by 2, then by 3.14 (π) and storing the product in the variable called 'circumference' */
- I/O (input-output) statements that read or write the values of variables from or to an I/O device; for example
- writeln("The value of the circumference of the circle: "+circumference); /* writing the variable named 'circumference' to the screen just after the text "The value of the circumference of the circle: " */
- writeln("____________"); /* writing the text "____________" on the screen (this is how the end of the program will be marked in the given example programs) */
- control structures (sequence, selection and iteration) that determine the order of execution of the statements of programs; for example
- a=2; b=3; c=a+b; writeln(c); /* let the value of the variable named 'a' be 2, then let the value of the variable named 'b' be 3, and then calculate the sum of 'a' and 'b' (a+b) and store it in the variable named 'c'; after that the sum of 'a' and 'b' ' will be written on the screen */ → sequence (of statements)
- if(i==1) { writeln("true"); } else { writeln("false"); } /* writing "true" (if 'i' is 1) or "false" (if 'i' is not 1) on the screen depending on the current value of the variable named 'i' */ → selection
- i=1; while(i<=n) { writeln(i); i=i+1; } /* writing the value of the variable named 'i' on the screen until the value of 'i' is less than or equal to the current value of the variable 'n' */ → iteration or repetition
- for(i=0;i<n;i=i+1) { writeln(i); } /* writing the value of the cycle variable named 'i' on the screen until the value of 'i' is less than the current value of the variable 'n' */ → loop or cycle which is used to repeat the block of statements given in curly brackets ({...}) a fixed number of times (i.e. exactly 'n' times in our case)
The three most important control structures that determine the execution order of the statements are as follows:
- sequence (of statements)
- selection (conditional single or multiple branching statements; not to be confused with jump statements, like 'break', 'continue' or 'return')
- iteration (cycle or loop)
The above control structures can be excellently illustrated with the help of flowcharts as follows: (cf. Essential Programming | Control Structures | by Diego Lopez Yse | Towards Data Science, 2022-10-09):
Below we present specific algorithms related to number systems. We will deal with the following algorithms:
- converting a binary number to a decimal number⇒
- converting a hexadecimal number to a decimal number⇒
- converting a decimal number to a binary number⇒
- conversion of an integer
- conversion of a fraction⇒
- converting a binary number to a hexadecimal number,⇒ and vice versa⇒
- converting a decimal number to a hexadecimal number⇒
- various representation of numbers⇒
- basic operations in the binary number system⇒
In most cases, the description of the algorithms is also presented with short JavaScript programs. An online JavaScript interpreter that can be used to try the example programs can be accessed as follows:
Online JavaScript Interpreter by Peter Jipsen, Chapman University (January 2013).
http://math.chapman.edu/~jipsen/js/ (2020-11-19)Note: If the link above does not work for some reason, please use the link here.
The flowcharts illustrating the JavaScript programs can be displayed using the online web application below:
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)
Examples of algorithms:
1. converting a binary number to a decimal number⇒
Example: 11012 = ?10
- multiply each digit of the binary number to be converted (e.g. 1101) by the positional value of the digit
- the first digit from the left is 1, its positional value is 23=8, so the product is 1*8=8
- the next digit is 1, its positional value is 22=4, so the product is 1*4=4
- the next digit is 0, its positional value is 21=2, so the product is 0*2=0
- the last digit is 1, its positional value is 20=1, so the product is 1*1=1
- adding up the obtained products, the result will be 8+4+1=13
digit positional value product 1 23=8 8 1 22=4 4 0 21=2 0 1 20=1 1 Total 13 Result:
11012 = 1310Check:
1310 = 8 + 4 + 1 = 1*23 + 1*22 + 0*21 + 1*20 = 11012 (ok)
The JavaScript program implementing the above algorithm is as follows:
// converting a binary number to a decimal number var x="1101"; writeln("Binary number: "+x); writeln(); var d=0; var posvalue=1; for(var i=1;i<x.length;i++) { posvalue*=2; } for(var i=0;i<x.length;i++) { var sz; if(x[i]=="1") { sz=1; } else { sz=0; } writeln(" Digit : "+sz); writeln(" Positional value: "+posvalue); var r=sz*posvalue; writeln(" Partial sum: "+r); d+=r; posvalue/=2; } writeln(); writeln("Decimal number: "+d); writeln("__________");
Examples of algorithms:
2. converting a hexadecimal number to a decimal number⇒
Example: 24C16 = ?10
- multiply each digit of the hexadecimal number to be converted (e.g. 24C) by the positional value of the digit
- the first digit from the left is 2, its positional value is 162=256, so the product is 2*256=512
- the next digit is 4, its positional value is 161=16, so the product is 4*16=64
- the last digit is C (it corresponds to 12 in the decimal number system), its positional value is 160=1, so the product is 12*1=12
- adding up the obtained products, the result will be 512+64+12=588
digit positional value product 2 162=256 512 4 161=16 64 C 160=1 12 Total 588 Result:
24C16 = 58810Check:
58810 = 512 + 64 + 12 = 2*256 + 4*16 + 12* 1 = 2*162 + 4*161 + 12*160 = 24C16 (ok)
The JavaScript program implementing the above algorithm is as follows:
// converting a hexadecimal number to a decimal number // var x=["2","4","C"]; var x="24C"; write("Hexadecimal number: "); for(var i=0;i<x.length;i++) { write(x[i]); } writeln(); writeln(); var d=0; var posvalue=1; for(var i=1;i<x.length;i++) { posvalue*=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(" Digit : "+sz); writeln(" Positional value: "+posvalue); var r=sz*posvalue; writeln(" Partial sum: "+r); d+=r; posvalue/=16; } writeln(); writeln("Decimal number: "+d); writeln("__________");
Examples of algorithms:
3. converting a decimal number to a binary number⇒
1. conversion of an integer
Example: 31410 = ?2
- divide the decimal number to be converted (e.g. 314) by 2 until the quotient is 0
- we do integer division, so the quotient will always be a whole number (i.e. an integer)
- in each step we write down the remainder of the division (0 or 1)
- the binary notation of the decimal number to be converted is obtained by writing the remainders of the integer divisions in reverse order (e.g. 100111010)
division quotient remainder 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 Result:
31410 = 1|0011|10102Note: since a binary number usually consists of quite a lot of digits (i.e. it often seems to be "long"), it is useful to divide the digits into groups of four from the right (using a separator, e.g. the | character).
Check:
1|0011|10102 = 1*28 + 1*25 + 1*24 + 1*23 + 1*21 = 256 + 32 + 16 + 8 + 2 = 31410 (ok)
The JavaScript program implementing the above algorithm is as follows:
// converting a decimal number to a binary number var x=314; writeln("Decimal number: "+x); writeln(); var b=""; var q=1; while(q>0) { q=Math.trunc(x/2); // integer division!! write(" Quotient: "+q); if(x%2==1) { b="1"+b; writeln(", remainder: "+1); } else { b="0"+b; writeln(", remainder: "+0); } x=q; } writeln(); writeln("Binary number: "+b); writeln("__________");
An alternative way to convert a decimal integer to a binary number is as follows:
- find the highest power of two that is less than or equal to the number to be converted; that will be the highest positional value of the binary number
- the digit corresponding to the found positional value will be '1';
- subtract the found positional value from the decimal number to be converted;
- considering the above result of the subtraction as a decimal number to be converted, we repeat steps 1 and 2 until the result of the subtraction is zero;
- in the binary notation of the decimal number to be converted, the digits to which we have not assigned the value '1' will have the value '0'.
Példa: 31410 = ?2
power of two decimal number to be converted
result of the subtractionbinary digit 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 Result:
31410 = 1|0011|10102
The JavaScript program implementing the above algorithm is as follows:
// converting a decimal number to a binary number by subtractions var x=314; writeln("Decimal number: "+x); writeln(); var b=""; var posvalue=1; while(2*posvalue<=x) { posvalue*=2; } while(posvalue>=1) { if(posvalue<=x) { b+="1"; writeln(" Digit: "+1); writeln(" Positional value: "+posvalue); x-=posvalue; } else { b+="0"; writeln(" Digit: "+0); writeln(" Positional value: "+posvalue); } posvalue/=2; } writeln(); writeln("Binary number: "+b); writeln("__________");
2. conversion of a fraction
For the sake of simplicity, let's assume that the decimal fraction to be converted is positive and less than 1.
Example: 0.687510 = ?2
- multiply the decimal number to be converted (e.g. 0.6875) by 2 until
- the fractional part is 0, or
- a given sequence of binary digits shows endless repetition.
- write the whole part of the product (which can be 0 or 1), and then subtract it from the product
- if the algorithm continues, the result of the above subtraction (i.e. the fractional part of the above product) is multiplied by 2 again
- repeat from step 2
- the binary notation of the decimal fraction to be converted is obtained by writing down the written whole parts of the products in the original order after the starting 0. of the number (e.g. 0.1011)
product whole part fractional part 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 Result:
0.687510 = 0.10112Notes:
(1) in the case of more than four binary digits, it is also worth dividing the sequence of digits into groups of four (from the left, just after the "binary point");
(2) if the whole part of the decimal number to be converted is greater than 0, convert the whole part and the fractional part of the decimal number separately into a binary number.Check:
0.10112 = 1*2−1 + 1*2−3 + 1*2−4 = 1/2 + 1/8 + 1/16 = 11/16 = 0.687510 (ok)
The JavaScript program implementing the above algorithm is as follows:
// converting a decimal fraction to a binary one var x=0.6875; writeln("Decimal fraction: "+x); writeln(); var maxi=50; var s=""; var i=1; while(x>0 && i<=maxi) { x*=2; if(x<1) { write(" whole part: 0,"); s+="0"; } else { write(" whole part: 1,"); s+="1"; x=x-1; } writeln(" fractional part: "+x); if(i%4==0) { writeln("..... "+i+". cycle ....."); s+=" "; } i++; } writeln(); writeln("Binary fraction (first "+maxi+" binary digits): 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.
A bináris egész számokat hexadecimális számokká alakító algoritmus lépései:
- az átváltandó kettes számrendszerbeli egész szám számjegyeit (pl. 1010|1101) jobbról négyes csoportokra osztjuk fel; a példa esetén ekkor
- jobbról az első csoport 1101
- jobbról a második csoport 1010
- a kapott négy bináris számjegyből álló csoportokat balról jobbra haladva egyenként tízes számrendszerbeli számokká alakítjuk (alkalmazva a korábban megismert 2. algoritmust⇒)
- 10102=8+2=1010
- 11012=8+4+1=1310
- az egyes csoportoknak megfelelő tízes számrendszerbeli számokat tizenhatos számrendszerbeli (hexadecimális) számjegyekké alakítjuk
- 10102=8+2=1010=A16
- 11012=8+4+1=1310=D16
- a kapott tizenhatos számrendszerbeli számjegyeket egymás után felírva megkapjuk a keresett hexadecimális számot
Eredmény: 1010|11012 = AD16
A fenti példa táblázatos formában:
1010|11012 = ?16
bin
számjegyhelyi érték szorzat hexa
számjegy1 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 = AD16Ellenő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 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
- alakítsuk át a hexadecimális számjegyeket egyenként (pl. balról jobbra haladva) négy számjegyből álló (4 bites) bináris számokká;
- ha szükséges, tegyünk be vezető nullákat, hogy a kapott bitsorozatok mindig 4 bitből álljanak
- balról jobbra haladva "olvassuk össze" a kapott négy bites bitsorozatokat (szükség esetén a bitsorozatok közé betehetünk elválasztó karaktereket (pl. függőleges vonalat vagy szóközt) a könnyebb olvashatóság kedvéért)
Példa: 2AD16 = ?2
- 216 = 00102
- A16 = 10102
- D16 = 10112
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:
- az átváltandó kettes számrendszerbeli egész szám számjegyeit (pl. 0.1011|0101) balról négyes csoportokra osztjuk fel; a példa esetén ekkor
- balról az első csoport 1011
- balról a második csoport 0101
- a kapott négy bináris számjegyből álló csoportokat balról jobbra haladva egyenként tízes számrendszerbeli számokká alakítjuk (alkalmazva a korábban megismert 2. algoritmust⇒)
- 10112=8+2+1=1110
- 01012=4+1=510
- az egyes csoportoknak megfelelő tízes számrendszerbeli számokat tizenhatos számrendszerbeli (hexadecimális) számjegyekké alakítjuk
- 10112=8+2+1=1110=B16
- 01012=4+1=510=516
- a kapott tizenhatos számrendszerbeli számjegyeket egymás után felírva megkapjuk a keresett hexadecimális számot
Eredmény: 0.1011|01012 = 0.B516
A fenti példa táblázatos formában:
0.1011|01012 = ?16
bin
számjegyhelyi érték szorzat hexa
számjegy1 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.B516Ellenő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: az átváltandó tízes számrendszerbeli számot kettes számrendszerbeli (bináris) számmá alakítjuk (ld. 3. algoritmus⇒)
- 2. lépés: az így kapott bináris számot tizenhatos számrendszerbeli (hexadecimális) számmá alakítjuk (ld. 4. algoritmus⇒)
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ámjegyhelyi érték szorzat hexa
számjegy0 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 = 13A16Ellenő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á:
- az átváltandó tízes számrendszerbeli számot (pl. 314) addig osztjuk 16-tal, amíg a hányados 0 nem lesz
- minden lépésben felírjuk az osztás maradékát (amely egy 0 és 15=F közötti szám lesz)
- az átváltandó szám hexadecimális számrendszerbeli alakját úgy kapjuk meg, hogy az osztások maradékait fordított sorrendben felírjuk
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); // integer division!! 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("__________");
Various representation of numbers in digital computers
In digital computers, data is represented in binary notation, as sequences of bits. In the following, we assume that the data is stored in an 'n' bit storage unit called a register. In a register, 'n' different bits can be stored independently which allows a total of m=2n different bit variations. So an 'n' bit register can store 'm' different (binary coded) data. The number 'm' is also called the modulus of the register.
For example,
– the modulus of an 8 bit register is m=256;
– the modulus of a 16 bit register is m=65536;
– the modulus of a 24 bit register is m=16,777,216;
– the modulus of a 32 bit register is m=4,294,967,296.Exactly m=2n different variations of binary coded data can be stored in an 'n' bit register.
Since we store individual bits in a register, an 'n' bit register can also be thought of as a series of one-bit storage units denoted by b0, b1, ... respectively (where each unit has a value of 0 or 1). Using such markup, a register can be described in a form of
bn−1bn−2...b2b1b0
where bn−1 stores (or represents) the most significant bit (MSB), and b0 the least significant bit (LSB). The meaning of MSB and LSB depends on the actual represention of data, e.g. when we deal with integers represented in a binary number system, MSB corresponds to the highest positional value, and LSB corresponds to the lowest positional value (i.e. the number of ones).Note that in the case of the representation of signed numbers (more precisely, when the sequence of bits stored in the register is interpreted as a signed number), the leftmost bit usually specifies the sign of the number:
for bn−1=0, the number stored in the register is positive;
for bn−1=1 the number stored in the register is negative.
In this case, the leftmost bit is called the sign bit.As for placing the bits of an unsigned binary number in a register, it is a general rule that
– the digit having the lowest positional value of the number is stored in the rightmost or LSB position in the register (i.e. which has the lowest sequence number, e.g. b0), and accordingly,
– the digit having the highest positional value of the number is stored in the leftmost or MSB position in the register (i.e. which has the highest sequence number, e.g. bn−1).If we store a given number in a register, the digits of the number can be assigned to the bits of the register in different ways. Accordingly, we can talk about the following coding or number representation methods:
- direct coding of binary numbers⇒
- two's complement representation of binary numbers⇒
- binary coded decimal (BCD) representation of signed or unsigned integers⇒
- floating point representation of real numbers⇒
(1) direkt kódolás
Ha egy regiszterben egy bináris számrendszerben ábrázolt nemnegatív egész számot tárolunk úgy, hogy a regiszter bitjeinek a szám bináris számjegyeit feleltetjük meg a helyi értékek megszokott sorrendjében (azaz az LSB-hez a legkisebb, 1-es helyiérték tartozik, majd (jobbról balra haladva) a következő bithez a 2-es helyiérték, utána a 4-es, 8-as stb.), akkor ún. direkt kódolásról (vagy egyenes kódolásról) beszélünk. Mivel direkt kódolás esetén csak nemnegatív számokat ábrázolunk, ezért nincs szükségünk előjelbitre.
Direkt kódolás esetén például egy 8 bites regiszterben tárolható legkisebb szám 0000|00002=010, a legnagyobb pedig 1111|11112=25510.
(2) kettes komplemens kódolás
Tároljunk egy 'n' bites (m=2n modulusú) regiszterben egész számokat a következőképpen:
- az előjelbit értéke nemnegatív számok esetén legyen 0, negatív számok esetén pedig 1 (így m/2 nemnegatív és m/2 negatív egész számot tudunk ábrázolni);
- ábrázoljuk a nemnegatív számokat direkt kódban;
- ábrázoljuk a negatív számokat úgy, hogy
- képezzük a negatív számok abszolút értékét direkt kódban,
- komplementáljuk az így kapott számot, azaz írjunk 0 helyett 1-et és 1 helyett 0-t (ez az ún. egyes komplemens kódolás, amit rendszerint "felülhúzással" jelölünk), és
- a komplementált számhoz adjunk hozzá binárisan 1-et.
Ezt a kódolást kettes komplemens kódolásnak nevezzük.
Ábrázoljunk példaként egy 8 bites regiszterben kettes komplemens kódban néhány számot (a bitsorozatok után alsó indexben megadott '2' most kettes komplemens kódban ábrázolt számot jelöl):
decimális érték kettes komplemens kód decimális érték kettes komplemens kód 010 0000|00002 110 0000|00012 −110 1111|11112 210 0000|00102 −210 1111|11102 310 0000|00112 −310 1111|11012 ... 2310 0001|01112 −2310 1110|10012 ... 12610 0111|11102 −12610 1000|00102 12710 0111|11112 −12710 1000|00012 −12810 1000|00002 Például −2310=1110|10012 mivel 0001|01112=1110|10002 (egyes komplemens) és ehhez 1-et binárisan hozzáadva 1110|10002+12=1110|10012 adódik.
Jegyezzük meg, hogy kettes komplemens kódban 12710 a legnagyobb ábrázolható pozitív szám, és −12810 a legkisebb ábrázolható negatív szám.Ha képezzük a −2310+2310 összeget 0001|01112+1110|10012=1|0000|00002 adódik, ami éppen a 8 bites regiszter m=256 modulusának 2-es számrendszerben ábrázolt értéke. Általánosan is igaz, hogy egy 'n' bites regiszterben (a megengedett −m/2≤x<m/2 számtartományon belül) egy kettes komplemens kódban ábrázolt negatív szám és a vele abszolút értékben megegyező nemnegatív szám összege a regiszter modulusát adja. Formálisan kifejezve: ha a megengedett számtartományon belül 'v' egy nemnegatív egész számot jelöl, 'w' pedig ennek kettes komplemens kódját, akkor v+w=m vagy másképpen kifejezve v+w=0 (mod m) teljesül.
Két fontos szabály:
- Egy kettes komplemens kódban ábrázolt negatív szám abszolút értékét ugyanazzal az algoritmussal kaphatjuk meg, mint ahogy egy negatív szám kettes komplemens kódját képeztük (azaz komplementálással és 1 bináris hozzáadásával).
- Például w=1010|01102 esetén v=0101|10012+12=0101|10102 vagyis |w|=9010
- Egy nemnegatív szám kivonását elvégezhetjük a szám kettes komplemens kódjának a hozzáadásával. A szabály alkalmazásakor a legmagasabb helyiértékű számjegyek összeadása után keletkező átvitelt figyelmen kívül kell hagyni.
- Például számoljuk ki az x=4910−2710 különbséget.
Legyen v=2710=0001|10112, ekkor w=−2710=1110|01002+12=1110|01012. Mivel 4910=0011|00012 ezért a keresett különbség
x=4910−2710=0011|00012+1110|01012=1|0001|01102
elhagyva a legmagasabb helyiértéken keletkező 1 bitet (az átvitelt), a különbségre a helyes x=0001|01102=2210 érték adódik.Negatív egész számokat kettes komplemens kódban ábrázolva a kivonást összeadásra tudjuk visszavezetni.
(3) binárisan kódolt decimális (BCD) számábrázolás
BCD számábrázolás esetén tízes számrendszerben megadott egész számokat kódolunk a decimális számjegyek adott számú biten történő bináris megadásával. A BCD számábrázolás két típusa:
– pakolt, csomagolt vagy tömörített ("packed") BCD esetén a decimális számjegyeket 4 biten (1 tetrádon) ábrázoljuk (egy bájt felső vagy alsó 4 bitje egy ún. fél bájt vagy tetrád, angolul "nibble");
– pakolatlan, kibontott vagy zónázott ("unpacked") BCD esetén a decimális számjegyeket 8 biten (1 bájton) ábrázoljuk (a felső 4 bitet az ún. zónabitek alkotják, az alsó 4 bit pedig az ábrázolandó decimális számjegy bináris alakját tartalmazza).
- BCD számábrázolás esetén a decimális számjegyeket helyiértékük szerint balról jobbra helyezzük el a számjegyek számára rendelkezésre álló bájtsorozatban.
- Pakolt BCD számábrázolás esetén egy bájton két számjegyet ábrázolunk (a magasabb helyiértékű számjegyet a "felső" 4 biten, az alacsonyabb helyiértékű számjegyet az "alsó" 4 biten tárolva). (Megjegyzés: az utolsó bájt alsó 4 bitjét a szám előjelének az ábrázolására is használhatjuk.)
Mivel így csak páros számú számjegyet tudunk ábrázolni, attól függően, hogy előjeles vagy előjel nélküli számot ábrázolunk, a következőképpen járhatunk el:
- előjel nélküli ábrázolás esetén: ha a decimális számjegyek száma nem páros, akkor a számjegyeket kiegészítjük egy vezető 0-val;
- előjeles számábrázolás esetén: ha a decimális számjegyek száma nem páratlan, akkor a számjegyeket kiegészítjük egy vezető 0-val.
- Pakolatlan BCD számábrázolás esetén egy bájton egy számjegyet ábrázolunk:
– a "felső" 4 biten (az ún. zónabiteken) egy előre rögzített bitsorozatot tárolunk (ez lehet pl. 0000 vagy FFFF);
– az "alsó" 4 biten pedig egy decimális számjegyet tárolunk bináris alakban.- Ha a számnak van előjele, az pakolt BCD kódolás esetén a számjegyek után helyezkedik el, pakolatlan BCD kódolás esetén pedig az utolsó számjegyet tartalmazó bájt "felső" 4 bitjén, az utolsó bájt zónabitjei helyett.
- Az előjelet négy biten ábrázolva az A, C, E vagy F hexadecimális számjegyek a '+' előjelet, a B vagy D számjegyek a '−' előjelet kódolják.
- Ha a memóriában tároljuk a számot, akkor a legmagasabb helyiértékű számjegy(ek) lesznek a legalacsonyabb memóriacímen ("big-endian order"). (Ezt a tárolási sorrendet követjük egy karakterlánc (string) karaktereinek, vagy egy tömb elemeinek a memóriában való tárolásakor.)
Számábrázolás a számítógépen: lebegőpontos számábrázolás
Lebegőpontos számábrázolás esetén normál alakban megadott valós számokat kódolunk adott pontossággal. Ennek alapja az, hogy az ábrázolandó 'x' valós számot
x = s*m*2k
normál alakban adjuk meg, ahol 's' a szám előjele (s=±1), 'm' a kettedes tört formában megadott ún. mantissza (m∈ℝ), és 'k' az ún. karakterisztika (k∈ℤ).A mantissza számjegyeinek (bitjeinek) a száma a számábrázolás pontosságát, a karakterisztika pedig az ábrázolható számok nagyságrendjét határozza meg (vö. Nyakóné Juhász 2011: 21).
A lebegőpontos számok ábrázolása
- egyszeres pontosságú valós számok esetén 32 biten,
- duplapontosságú valós számok esetén 64 biten történik.
A továbbiakban az egyszeres pontosságú, 32 bites lebegőpontos számábrázolással foglalkozunk. (Az Institute of Electrical and Electronics Engineers (IEEE) által a nyolcvanas években kiadott IEEE 754 nevű szabvány alapján, vö. Nyakóné Juhász 2011: 21-22).
Ha egyszeres pontossággal, 32 biten ábrázolunk egy lebegőpontos számot, akkor
– az előjelet a bal szélső 1 biten a szokásos módon,
– a karakterisztikát a következő 8 biten többletes kódolással,
– a mantisszát pedig a fennmaradó 23 biten fixpontos kódolással
ábrázoljuk.
b b b ... b b b b b b b ... b b b előjel (sign, 1 bit) karakterisztika (exponent, 8 bit) mantissza (fraction, 23 bit) Jelöljük
– az ábrázolt valós számot 'x'-szel;
– a karakterisztika tényleges értékét 'k'-val, az egyszeres pontosságú lebegőpontos számnak a karakterisztika számára fenntartott 8 bitjén direkt kódolással ábrázolt "többletes" (127-tel, ill. kis számok esetén 126-tal eltolt) értéket pedig exp-val;
– a mantissza tényleges értékét 'm'-mel, az egyszeres pontosságú lebegőpontos számnak a mantissza számára fenntartott 23 bitjén fixpontos kódolással ábrázolt értéket pedig frac-val.Három esetet különböztetünk meg:
(1) "normál" eset: a karakterisztika legalább −126, és az ábrázolt exponens legalább 1 (vagyis nem zérus)
Ha az ábrázolandó valós számra 2−126≤|x|<2128 teljesül, akkor
- a karakterisztika tényleges értékére −126≤k≤127 teljesül;
- a karakterisztika (direkt kódban) ábrázolt értékére 1≤exp≤254 teljesül;
- 'k' és 'exp' között a kapcsolatot
exp=k+127, ill. k=exp−127
módon fejezhetjük ki;- a mantissza tényleges értékére 1≤m<2 teljesül;
- a mantissza ábrázolt értékét kettedes tört formában frac=0.b1...b23 módon fejezhetjük ki, ahol bi a mantissza 2−i-dik helyiértékén álló bináris számjegy (1≤i≤23);
- ha a mantisszát kettedes törtben ábrázoljuk, 'm' és 'frac' között a kapcsolatot
m=1+frac, ill. m=1.b1...b23
módon fejezhetjük ki.Ha a karakterisztika (k) kódolt értéke nem zérus (vagyis a karakterisztika −126-nál nem kisebb egész szám), a mantissza tényleges értékét (m) egy olyan kettedes törttel fejezzük ki, amelynek egész része mindig 1 (vagyis a mantissza 1≤m<2 közötti valós szám). Az egyszeres pontosságú lebegőpontos számnak a mantissza számára fenntartott 23 bitje ilyenkor a mantissza tört részének bináris számjegyeit adja meg.Megjegyzések:
– a karakterisztika tényleges értékének (k) fenti módon történő kódolását ún. 127-es többletes kódolásnak nevezzük (ez k+127 direkt kódban történő ábrázolását jelenti adott számú (ti. 8) biten);
– a kettedestörtek számjegyeinek (az egész résznek és/vagy a tört résznek) adott számú biten történő ábrázolását nevezzük ún. fixpontos számábrázolásnak (a mantissza ábrázolása ezt a kódolási formát követi, mivel a mantissza tört részének bináris számjegyeit rögzített számú (ti. 23) biten adjuk meg);
– az (1) esetben ábrázolható legkisebb szám esetén exp=1 és frac=0, tehát
x(1),min=1.0000...*2−126=2−126;
– az (1) eset ekvivalens azzal, amikor a karakterisztika −125≤k≤128 közötti egész szám és a mantissza 1/2≤m<1 közötti valós szám (vagyis a mantisszát 0.1-re normáljuk). Ekkor a karakterisztikát 8 biten 126-os többletes kódban adjuk meg, azaz az exp=k+126 egész számot ábrázoljuk direkt kódban (1≤exp≤254), és a mantissza kettedestört alakjában a mantissza 0.1 utáni bináris számjegyeit ábrázoljuk a rendelkezésre álló 23 biten.(2) a zérushoz közeli ("kis") számok esete: a karakterisztika −126, és az ábrázolt exponens zérus
Ha az ábrázolandó valós számra 0≤|x|<2−126 teljesül, akkor
- a karakterisztika tényleges értéke k=−126 (és nem −127, mert ebben az esetben más kódolást használunk, mint "normál" esetben!);
- a karakterisztika (direkt kódban) ábrázolt értéke exp=0 (ez az előjelbit után egy nyolc bites 00000000 bitsorozatot jelent);
- 'k' és 'exp' között a kapcsolatot
exp=k+126, ill. k=exp−126
módon fejezhetjük ki (bár erre valójában most nincs is szükség, mert mind 'k', mind 'exp' értéke rögzített);- a mantissza tényleges értékére 0≤m<1 teljesül;
- a mantissza ábrázolt értékét kettedes tört formában frac=0.b1...b23 módon fejezhetjük ki, ahol bi a mantissza 2−i-dik helyiértékén álló bináris számjegy (1≤i≤23);
- ha a mantisszát kettedes törtben ábrázoljuk, 'm' és 'frac' között a kapcsolatot
m=0+frac, ill. m=0.b1...b23
módon fejezhetjük ki (a mantissza kettedestört alakjában a mantissza 0. utáni bináris számjegyeit ábrázoljuk a mantissza számára rendelkezésre álló 23 biten).Ha a karakterisztika (k) kódolt értéke zérus (vagyis a karakterisztika értéke −126), a mantissza tényleges értékét (m) egy olyan kettedes törttel fejezzük ki, amelynek egész része mindig 0 (vagyis a mantissza 0≤m<1/2 közötti valós szám). Az egyszeres pontosságú lebegőpontos számnak a mantissza számára fenntartott 23 bitje ilyenkor is a mantissza tört részének bináris számjegyeit adja meg. Ha a mantissza értéke zérus, akkor a lebegőpontos szám értéke is zérus (az előjeltől függetlenül).Megjegyzések:
– ha az (1) esetben a mantisszát 0.1-re normáljuk (azaz 1/2≤m<1 teljesül), akkor a (2) eset annak a speciális esetnek felel meg, amikor a karakterisztika k=−126 (és exp=0); de mivel szeretnénk a zérust is ábrázolni, most megengedjük az 1/2-nél kisebb nemnegatív mantisszákat is (vagyis ebben az esetben 0≤m<1 teljesül);
– a (2) esetben alkalmazott kódolás lehetővé teszi a zérus ábrázolását ("lebegőpontos nulla"), sőt valójában ez kétféleképpen is lehetséges: ha az egyszeres pontosságú lebegőpontos számok számára rendelkezésre álló 32 biten csupa 0 szerepel, "pozitív" zérusról, ha pedig az első bit 1, és utána 31 biten csupa 0 szerepel, "negatív" zérusról beszélhetünk;
– a (2) esetben ábrázolható legnagyobb szám m=0.1111... és exp=0 (azaz k=−126) miatt
x(2),max=0.1111...*2−126≲2−126.(3) túlcsordulás: a karakterisztika legalább 128, és az ábrázolt exponens 255 (azaz binárisan 1111|1111) (az abszolút értékben "túlságosan" nagy, ezért lebagőpontosan már nem ábrázolható számok esete)
Ha az ábrázolandó számra 2128≤|x| teljesül, akkor a valós szám már nem ábrázolható az egyszeres pontosságú lebegőpontos formátumban. Ekkor
- a karakterisztika tényleges értékére 128≤k teljesül (feltéve, hogy az (1) esethez hasonlóan a mantissza most is az 1≤m<2 tartományba esik);
- a karakterisztika (direkt kódban) ábrázolt értékére exp=255 teljesül (azaz a karakterisztika 8 biten ábrázolt alakja a 11111111 bitsorozat);
- a mantissza tényleges értéke és ábrázolt értéke tetszőleges lehet (ebben az esetben nem vesszük figyelembe).
Túlcsorduláskor az ábrázolt bitsorozatot a mantissza értékétől függetlenül nem számként értelmezzük, hanem az előjelbittől függően plusz, ill. minusz végtelenként (±∞). A túlcsordulás szokásos jelölése NaN ("not a number").
1. példa (vö. Nyakóné Juhász 2011: 22): Tekintsük az alábbi 32 bites bitsorozatot, amely egy egyszeres pontosságú lebegőpontos számot határoz meg:
x=1 10000111 101000000000000000000002
Határozzuk meg, ez milyen valós számnak felel meg!A lebegőpontos számábrázolás (1) esetét alapul véve
– mivel az előjelbit 1, ezért 'x' negatív;
– mivel k'=1000|01112=13510, ezért a karakterisztika értéke k=k'−127=8;
– mivel az 1-re normált mantissza m=1.101000...2, ezért
m=1+1/2+1/8=8/8+5/8=13/8Tehát a keresett valós szám 28=256 miatt
x=−13/8*28=−13/8*256=−416Vizsgáljuk meg azt az esetet, amikor a mantisszát 0.1-re normáljuk. Ekkor a következőket kapjuk:
– mivel az előjelbit 1, ezért 'x' negatív;
– mivel k'=1000|01112=13510, ezért a karakterisztika értéke k=k'−126=9;
– mivel a 0.1-re normált mantissza m=0.1101000...2, ezért
m=1/2+1/4+1/16=8/16+4/16+1/16=13/16
Tehát a keresett valós szám 29=512 miatt
x=−13/16*29=−13/16*512=−416
megegyezik az előző értékkel.
2. példa: Tekintsük az alábbi 32 bites bitsorozatot, amely most is egy egyszeres pontosságú lebegőpontos számot határoz meg:
x=0 00000000 101000000000000000000002
Határozzuk meg, ez (közelítőleg) milyen valós számnak felel meg!A lebegőpontos számábrázolás (2) esetét alapul véve
– mivel az előjelbit 0, ezért 'x' pozitív;
– mivel k'=0000|00002=010, ezért a karakterisztika értéke k=k'−126=−126;
– mivel a 0.-val kezdődő mantissza m=0.101000...2, ezért
m=1/2+1/8=5/8Tehát a keresett valós szám
x=5/8*2−126≈7.3468...10−39
Alapműveletek kettes számrendszerben
Alapműveletek:
1. összeadás és kivonás
Mivel a kettes számrendszerben csak két számjegyünk van, az egy számjegyből álló kettes számrendszerbeli számok összeadásához az alábbi táblázatra van szükségünk:
+ 0 1 0 0 1 1 1 10 A táblázatból látható, hogy 12+12=102 vagyis két 1-es összeadása két számjegyből álló számot eredményez. Ezt úgy is megfogalmazhatjuk, hogy két 1-es összeadásakor az alacsonyabb helyiértékről ún. átvitel keletkezik a magasabb helyiértékre.
Mivel az azonos helyiértékű számjegyek összeadásakor az átvitelt is figyelembe kell vennünk, érdemes a fenti táblázatot bővíteni egy harmadik oszloppal, amelyben az átvitelt jelentő bitek szerepelnek:
összeadandó bitek eredmény 0 0 0 0 1 0 0 1 0 1 0 1 0 0 1 1 1 1 0 10 1 0 1 10 0 1 1 10 1 1 1 11 Lássunk ezek után néhány példát bináris számok összeadására. (A kivonást a negatív egész számok kettes komplemens kódban történő ábrázolásával összeadásra tudjuk visszavezetni.)
Legyenek 'p', 'q' és 'r' 8 bites regiszterek, amelyekben a számokat direkt kódban ábrázoljuk.
Példa összeadásra:
Legyen p=0010|10112 és q=0011|10102; r=p+q=?2
r=p+q p = 0 0 1 0 | 1 0 1 1 q = 0 0 1 1 | 1 0 1 0 átvitel 0 1 1 1 | 0 1 0 0 r = 0 1 1 0 | 0 1 0 1 Eredmény: r=0110|01012=10110
Ellenőrzés: p=4310, q=5810, r=10110, vagyis p+q=r teljesül, tehát jól számoltunk.
Ha direkt kódban ábrázolt bináris számok összeadásakor az utolsó (legmagasabb helyiértékű) biten átvitel keletkezik, akkor a két szám összege túl nagy lesz, ezért már nem ábrázolható az 'r' regiszterben. Ilyen esetekben túlcsordulásról beszélünk.
Példa kivonásra:
Legyen p=0110|10112 és q=0011|01102; r=p−q=?2
r=p−q p = 0 1 1 0 | 1 0 1 1 q = 0 0 1 1 | 0 1 1 0 átvitel 0 1 1 0 | 1 0 0 0 r = 0 0 1 1 | 0 1 0 1 Megjegyzés: az átvitel sorban szereplő biteket a felette levő sor (a 'q' kivonandó) bitjeihez kell hozzáadni.
Eredmény: r=0011|01012=5310
Ellenőrzés: p=10710, q=5410, r=5310, vagyis p−q=r teljesül, tehát jól számoltunk.
Legyenek 'p', 'q' és 'r' ismét 8 bites regiszterek, amelyekben a számokat kettes komplemens kódban ábrázoljuk.
Példa:
Legyen p=1010|10112 és q=0001|10102; r=p+q=?2
p = 1 0 1 0 | 1 0 1 1 q = 0 0 0 1 | 1 0 1 0 átvitel 0 1 1 1 | 0 1 0 0 r = 1 1 0 0 | 0 1 0 1 Eredmény: r=1100|01012
Ellenőrzés:
– mivel 'p' negatív, |p|=0101|01002+12=0101|01012=8510 tehát p=−8510;
– q=0001|10102=2610;
– mivel 'r' is negatív, |r|=0011|10102+12=0011|10112=5910 tehát r=−5910.
Mivel p=−8510, q=2610, r=−5910, ezért p+q=r teljesül, tehát jól számoltunk. Az elvégzett összeadás egyenértékű a 2610−8510=−5910 kivonással, amit a példában a negatív számokat kettes komplemens kódban ábrázolva összeadásra vezettünk vissza.
2. szorzás
Direkt kódban ábrázolt kettes számrendszerbeli számok esetén a tizes számrendszerben jól ismert szorzási algoritmust alkalmazhatjuk. Jegyezzük meg a következőket:
- a kettővel való szorzás jobbról egy 0 hozzáírását jelenti a szorzandó számhoz (szorzáskor ezeket a 0-kat általában nem írjuk ki, csak a részletszorzatok egy helyiértékkel való eltolásával jelöljük őket);
- 2k-val való szorzás (k=1,2,...) jobbról 'k' darab 0 hozzáírását jelenti a szorzandó számhoz;
- mivel a szorzó csak 0 és 1 számjegyekből áll, a részletszorzatok vagy csupa zérusból állnak, vagy magából a szorzandóból (értelemszerűen 2 megfelelő hatványával szorozva, azaz "eltolva" a részletszorzatokat).
Legyenek 'p', 'q' és 'r' 8 bites regiszterek, amelyekben a számokat direkt kódban ábrázoljuk.
Példa szorzásra:
Legyen p=0000|10112 és q=0000|10102; r=p*q=?2
p*q = 0 0 0 0 1 0 1 1 * 00001010 + 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 r = 0 0 0 0 1 1 0 1 1 1 0 Ha a szorzó kettőnél több 1-est tartalmaz akkor a táblázatban kettőnél több kettes számrendszerbeli számot kell összeadnunk. Ilyenkor a táblázatba több segédsort is beírhatunk, amelyek az egyes részösszegeket (és szükség esetén az ezekhez tartozó átviteleket) tartalmazzák.
Eredmény: r=0110|11102=11010
Ellenőrzés: p=1110, q=1010, r=11010, vagyis p*q=r teljesül, tehát jól számoltunk.
Ha a szorzat túl nagy, és ezért már nem ábrázolható a 8 bites 'r' regiszterben, túlcsordulásról beszélünk.
3. osztás
Direkt kódban ábrázolt kettes számrendszerbeli számok esetén a tizes számrendszerben jól ismert osztási algoritmust alkalmazhatjuk.
Mivel az osztó csak 0 és 1 számjegyekből áll, az előző lépésben elvégzett kivonás maradékából és az osztó kiválasztott ("hozzáírt") számjegyéből kivonandó részletszorzatok vagy csupa zérusból állnak, vagy magából a szorzandóból.
Legyenek 'p', 'q' és 'r' 8 bites regiszterek, amelyekben a számokat direkt kódban ábrázoljuk.
Példa osztásra:
Legyen p=1100|10112 és q=0000|10102; r=p/q=?2
p/q = 1 1 0 0 1 0 1 1 : 1 0 1 0 = 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 − 1 0 1 0 0 0 1 0 1 − 0 0 0 0 0 1 0 1 0 − 1 0 1 0 0 0 0 0 1 − 0 0 0 0 0 0 0 1 1 − 0 0 0 0 d = 0 0 1 1 Ha az osztó (q) nincs meg maradék nélkül az osztandóban (p), akkor maradék képződik (d), amit a táblázat utolsó sora mutat. Ilyenkor maradékos osztást hajtottunk végre.
Eredmény:
az osztó: r=0001|01002=2010
a maradék: d=0000|00112=310
Ellenőrzés: p=20310, q=1010, r=2010, d=310, vagyis p=q*r+d teljesül, tehát jól számoltunk.
Általánosan egy 'b' alapszámú számrendszerben a számok a következő formában írhatók le ("ábrázolhatóak"):
A képletben
Például legyen az ábrázolt szám 314 a tízes számrendszerben (ezt 31410 módon jelölhetjük, ha egyszerre több számrendszerrel is dolgozunk). A fenti képlet alapján a számot
31410 = 3*102+2*101+4*100
= 300+20+4
formában írhatjuk fel.
Egy másik példaként legyen az ábrázolt szám 2.718 a tízes számrendszerben. A fenti képlet alapján a számot
2.71810 = 2*100+7*10−1+1*10−2+8*10−3
= 2+7/10+1/100+8/1000
formában írhatjuk fel.
Az alábbiakban a számrendszerek közötti átváltást öt típusfeladat segítségével gyakorolhatjuk:
16 | = | 0 | = | 0 | = | 10 |
---|
16 | = | 0 | = | 0 | = | 10 |
---|
2 | = | 0 |
---|---|---|
0 | ||
0 | ||
0 | ||
0 | ||
10 |
Egy adott számrendszerbeli számot átválthatunk decimális számmá az ún. Horner-elrendezést használva is. Legyen például 111001102 az átváltandó szám.
1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | |
---|---|---|---|---|---|---|---|---|
2 | 1 | 2*1+1=3 | 2*3+1=7 | 2*7+0=14 | 2*14+0=28 | 2*28+1=57 | 2*57+1=115 | 2*115+0=230 |
A Horner-táblázat felépítése:
– a táblázat két sorból áll;
– a táblázat első sora a második cellától kezdve az átváltandó szám számjegyeit tartalmazza;
– a táblázat második sorának első cellájába az átváltandó szám számrendszerének alapja kerül;
– a táblázat második sorának második cellájába a felette levő számjegyet másoljuk be.
Az algoritmus lényege, hogy
– a táblázatban balról jobbra haladva és
– a második sor harmadik cellájától kezdve egymás után kitöltjük a táblázat második sorának celláit.
Az egyes cellák értékét úgy számítjuk ki, hogy
– az előző cella értékét (pl. 1) szorozzuk a számrendszer alapjával (pl. 2-vel) és
– a szorzathoz hozzáadjuk a cella felett (az első sorban) levő cellában levő számjegyet (pl. 1-et).
Az első sorban ábrázolt, megadott számrendszerbeli szám tízes számrendszerbeli értékét a második sor utolsó (jobb szélső) cellájának értéke adja.
Próbáljuk ki egy tetszőleges (2-16 alapú) számrendszerbeli, max. 8 számjegyből álló szám megadásával a Horner-elrendezést:
A számrendszerbeli szám:
1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | |
---|---|---|---|---|---|---|---|---|
2 | 1 | 3 | 7 | 14 | 28 | 57 | 115 | 230 |
Egy decimális szám kettes számrendszerbeli alakját megkaphatjuk úgy, hogy
(1) a számot elosztjuk 2-vel, és leírjuk az osztás eredményeként kapott hányadost és maradékot;
(2) a leírt hányadost elosztjuk 2-vel, és ismét leírjuk az osztás eredményeként kapott hányadost és maradékot;
(3) és ezt addig folytatjuk, míg a hányados értéke 0 nem lesz.
A kettes számrendszerbeli alakot a kapott maradékok szolgáltatják, fordított sorrendben felírva (azaz az utoljára kapott maradék lesz a kettes számrendszerbeli szám legmagasabb helyi értékű számjegye).
hányados | osztás | maradék |
---|---|---|
átváltandó decimális szám:
bináris helyi érték és számjegy hexadecimális érték | összeg | |||||||||||
2048 | 1024 | 512 | 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |
256 | 16 | 1 |
(1) a hexadecimális számrendszer számjegyei
hexadecimális számjegy |
---|
decimális érték |
bináris érték |
(2) 2 hatványai
hatvány | érték |
---|
(3) 16 hatványai
hatvány | érték |
---|
további információk:
Számrendszer - Wikipédia. (2021-02-21)
Számrendszerek az informatikában - Wikipédia. (2021-02-21)