Reprezentacja liczb całkowitych w dowolnym systemie pozycyjnym
System pozycyjny
System pozycyjny to taki sposób reprezentowania liczby, w którym wartość liczby zależy od pozycji cyfry w ciągu cyfr.Liczba zapisana w dowolnym systemie pozycyjnym
an-1 an-2... a1a0gdzie:
- n to ilość cyfr tworzących daną liczbę
- a to cyfra stojąca na pozycji n-1
Rozwinięcie dowolnej liczby zapisuje się według poniższego wzoru
an-1⋅pn-1+ an-2⋅pn-2+...+ a1⋅p1+ a0⋅p0gdzie p, to podstawa systemu
Przykład rozwinięcia liczby dziesiętnej
532=5⋅100+3⋅10+2⋅1=5⋅102+3⋅101+2⋅100Jak odczytać wartość liczby zapisanej w systemie dwójkowym?
Aby obliczyć wartość dziesiętną liczby zapisanej w systemie dwójkowym korzystamy ze wzoru na rozwinięcie, w którym podstawą systemu jest liczba 2 ( w systemie trójkowy jest 3 itd)Liczba 101011(2)=?(10)
1⋅25+0⋅24+1⋅23+0⋅22+1⋅21+1⋅20=25+23+21+20=32+8+2+1=43Ciąg bitów
Ciąg bitów jako impulsy prądu mogą być binarnym rozwinięciem liczby
Najbardziej znaczący bit stoi z lewej strony, a najmniej znaczący z prawej strony rozwinięcia. Możemy zadać pytanie: Jaka jest wartość ciągu bitów przedstawionych na drugim wykresie?
011010(2)=?(10)
0⋅25+1⋅24+1⋅23+0⋅22+1⋅21+0⋅20=24+23+21=16+8+2=26
System szesnastkowy
System szesnastkowy oprócz cyfr zawiera symbole pierwszych sześciu wielkich liter alfabetu, czyli A, B, C, D, E i F. Symbole te odpowiednio odpowiadają wartościom 10, 11, 12, 13, 14, 15.
Przykładowo liczba szesnastkowa 4AD(16) w systemie dziesiętnym odpowiada wartości:
4AD=4⋅162+A⋅161+D⋅160=4⋅162+10⋅161+13⋅160=4⋅256+10⋅16+13⋅1=1197(10)Schemat Hornera- zamiana z dowolnego systemu na dziesiętny
Liczba z dowolnego systemu pozycyjnego spełnia warunek wielomianu
gdzie:
- a, to liczba z pozycji (n-1)
- p, to podstawa systemu
Możemy skorzystać ze schematu Hornera do obliczenia jej wartości w systemie dziesiętnym. Czyli sprowadzić liczbę z dowolnego systemu pozycyjnego do systemu dziesiętnego
Przykładowy program, który to realizuje napisany w Visual Studio C#
Proponowany kod funkcji zamieniającej liczbę z dowolnego systemu na dziesiętny wykorzystuje funkcję zamieniajacą wasrtość symbolu lietrowego na wartość liczbową. Na przykład A to 10... F to 16.
Poniżej kod funkcji ustalającej wartość symbolu A, B ... F
Wskazówka:
private byte Wartosc(Char znak)
{
byte a = 0;
switch (znak)
{
case 'A': a = 10; break;
case 'B': a = 11; break;
case 'C': a = 12; break;
case 'D': a = 13; break;
case 'E': a = 14; break;
case 'F': a = 15; break;
default: a = Convert.ToByte(znak - '0'); break;
}
return a;
}
Kod funkcji zamieniającej liczbę z dowolnego systemu na dziesiętny wykorzystujacy schemat Hornera
Wskazówka:
//s- to łańcuch znaków podanej liczby
//p- podstawa systemu
private long DowolnyNaDziesietny(String s, byte p)
{
long wynik = 0;
int i = 0;
while (i < s.Length - 1)
{
wynik = (wynik + Wartosc(s[i])) * p;
i++;
}
wynik += Wartosc(s[i]);
return wynik;
}
Poniżej pełny kod źródłowy klasy Form głównej formatki aplikacji
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _1AlgPozycyjneReprezentacjeliczb
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private byte Wartosc(Char znak)
{
byte a = 0;
switch (znak)
{
case 'A': a = 10; break;
case 'B': a = 11; break;
case 'C': a = 12; break;
case 'D': a = 13; break;
case 'E': a = 14; break;
case 'F': a = 15; break;
default: a = Convert.ToByte(znak - '0'); break;
}
return a;
}
//s- to łańcuch znaków podanej liczby
//p- podstawa systemu
private long DowolnyNaDziesietny(String s, byte p)
{
long wynik = 0;
int i = 0;
while (i < s.Length - 1)
{
wynik = (wynik + Wartosc(s[i])) * p;
i++;
}
wynik += Wartosc(s[i]);
return wynik;
}
private void Form1_Load(object sender, EventArgs e)
{
//ustaw pierwszy indeks w combobox na aktywny
comboBox1.SelectedIndex = 0;
comboBox2.SelectedIndex = 0;
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
//zabezpiecz przed znakami nienumerycznymi
if (e.KeyChar == 8) return;//wyskocz jak BackSpace
if (e.KeyChar < '0' || e.KeyChar > '9') e.Handled = true;
}
private void button3_Click(object sender, EventArgs e)
{
//zamień z dwolonego na dziesietny
if (textBox2.Text.Length < 1)
{
MessageBox.Show("Nie podano liczby!",
"Komunikat",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return;
}
byte p = Convert.ToByte(comboBox2.Text);
label4.Text = DowolnyNaDziesietny(textBox2.Text, p).ToString();
}
}
}
Kod programu w C#
Zwróć uwagę, że metody opisujące funkcje są zdefiniowane jako statyczne (patrz słowo kluczowe static). Podstawa systemu jest zapisywana w zmiennej lokalnej o nazwie p, zdefiniowanej jako typ byte. Wartość podawanej liczby zapisana jest w zmiennej lokalnej o nazwie sLiczba, zdefiniowanej jako typ String
Wskazówka:
using System;
using System.Reflection.PortableExecutable;
namespace MyApp // Note: actual namespace depends on the project name.
{
internal class Program
{
static byte Wartosc(Char znak)
{
byte a = 0;
switch (znak)
{
case 'A':a=10; break;
case 'B': a = 11; break;
case 'C': a = 12; break;
case 'D': a = 13; break;
case 'E': a = 14; break;
case 'F': a = 15; break;
//dla pozostałych znaków zwróć różnice z kodu ASCII
//'0' to pozycja 48, czyli znak '2'-'0' odpowiada
//50-48=2, co zapewnia uniwersalność konwersji znaków
default: a=Convert.ToByte(znak-'0'); break;
}
return a;
}
static long DowolnyNaDziesietny(String s, byte p)
{
//s to podana liczba jako łańcuch znaków
//p to podstawa systemu
long wynik = 0;
int i=0;
while (i < s.Length-1)
{
wynik = (wynik + Wartosc(s[i])) * p;
i++;
}
wynik += Wartosc(s[i]);
return wynik;
}
static void Main(string[] args)
{
Console.WriteLine("Witaj w CzD!");
Console.WriteLine("Zamiana liczby z dowolnego systemu na dziesiętny");
Console.WriteLine("Podaj podstawę systemu (2<=p<=16)");
byte p=Convert.ToByte(Console.ReadLine());
Console.WriteLine("Podaj liczbę z wybranego systemu");
String sLiczba=Console.ReadLine();
Console.WriteLine("Wartość liczby po zamianie na system dziesiętny:");
Console.WriteLine(DowolnyNaDziesietny(sLiczba, p));
}
}
}
Wynik działania programu
Kod programu w C++
Ten sam program napisany pod konsolę w C++ nieznacznie się różni. Pierwsze zauważalne różnice dotyczą użytych bibliotek i przestrzeń nazw modułu std
Wskazówka:
#include <iostream>
#include <string.h>
using namespace std;
Pozostałe główne różnice to zmiana typu z byte na int dla funkcji Wartosc (patrz kod programu)
Wskazówka:
#include <iostream>
#include <string.h>
using namespace std;
int Wartosc(char znak) {
int a = 0;
switch (znak)
{
case 'A':a = 10; break;
case 'B': a = 11; break;
case 'C': a = 12; break;
case 'D': a = 13; break;
case 'E': a = 14; break;
case 'F': a = 15; break;
//dla pozostałych znaków zwróć różnice z kodu ASCII
//'0' to pozycja 48, czyli znak '2'-'0' odpowiada
//50-48=2, co zapewnia uniwersalność konwersji znaków
default: a = (int)(znak - '0'); break;
}
return a;
}
long DowolnyNaDziesietny(string s, int p)
{
//s to podana liczba jako łańcuch znaków
//p to podstawa systemu
long wynik = 0;
int i = 0;
while (i < s.length() - 1)
{
wynik = (wynik + Wartosc(s[i])) * p;
i++;
}
wynik += Wartosc(s[i]);
return wynik;
}
int main()
{
cout << "Witaj w CzD!\n";
cout << "Zamiana liczby z dowolnego systemu na dziesietny\n";
cout << "Podaj podstawe systemu (2<=p<=16)\n";
int p;
cin >> p;
cout << "Podaj liczbe \n";
string sLiczba = "";
cin >> sLiczba;
cout<<"Wartosc liczby po zamianie na system dziesietny:\n";
cout << DowolnyNaDziesietny(sLiczba, p);
return 0;
}
Wynik działania programu
Przedstawione trzy rozwiązania tego samego problemu nieznacznie się różnią. Różnice wynikają z właściwości metod użytych języków. Ciało algorytmu zamieniającego dowolną liczbę z dowolnego sytemu liczbowego na system dziesiętny pozostało bez zmian.