1. PrevodDoSoustav

1.2. C#

Načtení celého čísla z desítkové soustavy do proměnné n (která je zároveň skutečným parametrem metody Prevod) ve statické hlavní metodě je realizováno pomocí příkazu TryParse - viz Kód 1. Pokud uživatel zadal nevalidní číslo např. text, je proměnná inicializována přednastavenou počáteční hodnotou specifikovanou pro datový typ int - jedná se totiž o metodu s výstupními parametry. Výsledek převodu ve formě textového řetězce je vypsán v následujícím příkazu Console.WriteLine, kde je před výsledný textový řetězec statické metody Prevod připojen text "Výsledek: ". 

static void Main(string[] args)
{
    /* Deklarace: 'n' ... číslo z desítkové soustavy, které má být převedeno
     * do vybrané soustavy (dvojkové - binární, šestnáctkové - hexadecimální) */
    int n;
 
    Console.WriteLine("Převod čísla do soustavy");
 
    // Výzva k zadání čísla
    Console.Write("Zadejte číslo, které má být převedeno: ");
    // Načtení konvertovaného čísla
    int.TryParse(Console.ReadLine(), out n);
    
    // Výpis konvertovaného čísla do požadované soustavy
    Console.WriteLine("Výsledek: " + Prevod(n));
}

Kód 1: Program PrevodDoSoustav - deklarace hlavní statické metody Main 

Do deklarované metody Prevod bylo posláno načtené číslo určené k převodu - viz Kód 2. Tento parametr je předán hodnotou, tzn. jeho hodnota je nakopírována do formálního parametru n. V úvodu těla metody jsou deklarovány následující proměnné:

  • p ... počet bitů
  • c ... zbytek po celočíselném dělení
  • d ... dělitel (základ soustavy)
  • s ... výstupní text (převedené číslo)
  • i ... pozice bitu ve výstupním textu
  • soustava ... index vybrané soustavy

Po inicializaci, tj. přiřazení prázdného textového řetězce výslednému textovému řetězci s, je pomocí cyklu s podmínkou na konci zajištěno načtení validního indexu typu soustavy (0 ... dvojková, 1 ... šestnáctková). Kontrola validity je provedena v podmínce cyklu pomocí operátoru nebo ||. Pokud index typu soustavy je menší než nula nebo větší než 1, je znovu proveden výpis výzvy k zadání indexu a jeho opětovné načtení.

Druhý cyklus s podmínkou na konci je určen pro výběr validního počtu bytů, který je uložen do proměnné p. Tato proměnná je zejména určena pro uložení počtu pozic s jednotlivými hodnotami uložených ve výsledném textu, obsahující převedené číslo do vybrané soustavy. Dočasně uložená hodnota počtu bytů je nahrazena novou hodnotou, která je vypočtena násobením této hodnoty počtem pozic, které jsou potřebné pro uložení jednoho bytu v konkrétní soustavě - pro dvojkovou soustavu je to 8 pozic (příklad týkající se uložení čísla 90 na 1 B ve dvojkové soustavě jsme uvedli v předchozí analýze). Výsledný textový řetězec bude vypadat takto: "0101 1010". Požadujeme, aby pro lepší čitelnost byla po každé 4 pozici do textového řetězce vložena mezera. U šestnáctkové soustavy je zapotřebí pouze 2 pozic pro uložení 1 B (pro zápis čísla 90 stačila pouze 1 číslice a 1 písmeno, tj. "5A").  

Jádrem výpočtu jednotlivých hodnot ve výsledném řetězci je cyklus s krokem. Řídící proměnná i tohoto cyklu symbolizuje jednotlivé pozice ve výsledném textovém řetězci. Tento cyklus probíhá od 1 do počtu vypočtených pozic, uložených v proměnné p. Hodnota na pozici je rovna zbytku celočíselného dělení konvertovaného čísla základem soustavy (dělitelem). Po vypočtení hodnoty na pozici je zapotřebí tuto hodnotu konvertovat na číslici, nebo písmeno. Rozhodnutí, zda se jedná o konverzi celočíselné hodnoty zbytku uložené v c na číslici, nebo na písmeno, je zajištěno pomocí podmínky c < 10. Pokud je zbytek menší než 10, jedná se o konverzi čísel v rozmezí 0 ÷ 9 na číslici. V opačném případě je hodnota ve zbytku převedena na písmeno: 

  • Konverze čísel na číslice je umístěna ve složeném příkazu za podmínkou. Konverze celočíselné hodnoty na znak je provedena pomocí přetypování (char). Podstatou konverze je nalezení znaku na určité pozici v ASCII. Tato celočíselná pozice znaku je vypočtena ze součtu zbytku po celočíselném dělení, ke kterému je přičteno celé číslo, reprezentující pozici znaku '0' v ASCII (získaného pomocí (int)'0'). Takto získaný znak připojíme ke stávajícímu výslednému řetězci
  • Konverze čísla na písmeno je umístěna ve složeném příkazu za else. Je zde použito stejného principu jako v předchozí konverzi s tím rozdílem, že je vypočteno, o kolik pozic se musíme v ASCII tabulce posunout od písmene 'A'

Pro vizuální přehlednost je ve výsledném textovém řetězci za každý výpis hodnot na čtyřech pozicích umístěna mezera. Tento trik je proveden pomocí podmínky i % 4 == 0.

Před vstupem do další iterace musí být přepočtena hodnota uložená v proměnné n. Tato hodnota je výsledkem celočíselného dělení základem soustavy. 

Pokud jsme provedli zápis hodnot na všech pozicích (tzn. proběhly všechny iterace v cyklu s krokem) a stále je v proměnné n hodnota větší než 0, tj. n > 0, znamená to, že došlo k přetečení. Uživatel chtěl do konvertovaného čísla ve vybrané soustavě uložit větší hodnotu, než je schopno pojmout (rozsah proměnné záleží na zvoleném počtu bytů). Informaci o přetečení připojíme do výsledného textového řetězce s, který je návratem volané statické metody Prevod - viz Kód 2.

/* Metoda s textovým návratem - převod čísla (parametr 'n') z desítkové soustavy 
 * do dvojkové (binární), nebo šestnáctkové (hexadecimální) soustavy */ 
static string Prevod(int n)
{
    /* Deklarace: 'p' ... počet bitů; 'c' ... zbytek po celočíselném dělení; 
     * 'd' ... dělitel (základ soustavy); 's' ... výstupní text (převedené číslo); 
     * 'i' ... pozice bitu ve výstupním textu; 'soustava' ... index vybrané soustavy */
    int p, c, d, i, soustava;
    string s;
 
    // Inicilizace - výstupní text je nastaven na prázdnou hodnotu
    s = "";
 
    // Validace indexu zvoleného typu soustavy
    do
    {
        // Výzva k výběru typu soustavy
        Console.Write("Zadejte index soustavy (0 ... dvojková, 1 ... šestnáctková): ");
 
        // Načtení indexu zvoleného typu soustavy
        int.TryParse(Console.ReadLine(), out soustava);
    }
    while (soustava < 0 || soustava > 1);
 
    // Validace zvoleného počtu bytů
    do
    {
 
        // Výzva k zadání počtu bytů (počet pozic ve výsledném řetězci)
        Console.Write("Zadejte počet bytů (1, 2, 4, 8): ");
 
        // Načtení počtu bytů - následně bude převeden na bity
        int.TryParse(Console.ReadLine(), out p);
    }
    while (p != 1 && p != 2 && p != 4 && p != 8);
 
    // Test, zda byla vybrána dvojková soustava
    if (soustava == 0)
    {
        /* Byla vybrána dvojková (binární) soustava - nastavení hodnoty 
         * počtu bitů v závislosti na počtech bytů (1 byte = 8 bitů v binární soustavě) */
        p = p * 8;
 
        // Nastavení dělitele na hodnotu 2
        d = 2;
    }
    else
    {
        /* Byla vybrána šestnáctková (hexadecimální) soustava - nastavení hodnoty počtu 
         * bitů v závislosti na počtech bytů (1 byte lze zobrazit na 2 pozice v šestnáctkové 
         * soustavě) */
        p = p * 2;
 
        // Nastavení dělitele na hodnotu 2
        d = 16;
    }
 
    // Cyklus s krokem – pro všechny bity (počet bitů uložen v proměnné 'p')
    for (i = 1; i <= p; i++)
    {
        // Nastavení zbytku = hodnota po celočíselném dělení konvertovaného čísla dělitelem
        c = n % d;
 
        // Test, zda se jedná o konverzi čísla na číslici, nebo čísla na písmeno (podle hodnoty v 'c')
        if (c < 10)
        {
            /* Pokud je zbytek menší než 10 (dvojková soustava) jedná se o konverzi čísla na číslici (znak)
             * Výstupní text = vložení znaku před stávající text (znak je v ASCII na pozici, která 
             * je rovna hodnotě zbytku + ordinální hodnota znaku '0') */
            s = (char)(c + (int)'0') + s;
        }
        else
        {
            /* Pokud je zbytek větší nebo roven 10 (šestnáctková soustava) jedná se o konverzi čísla 
             * na písmeno (znak) - výstupní text = vložení znaku před stávající text 
             * (znak je v ASCII na pozici, která je rovna hodnotě zbytku - 10 + 
             * ordinální hodnota znaku 'A') */
            s = (char)(c - 10 + (int)'A') + s;
        }
 
        // Pokud je bit na násobkem čtvrté pozice ...
        if (i % 4 == 0)
        {
            // Vložení mezery do výstupního textu před stávající text
            s = " " + s;
        }
 
        // Vstupní číslo = celočíselné dělení stávajícího konvertovaného čísla dělitelem
        n = n / d;
    }
 
    // Pokud je konvertované číslo větší než nula ...
    if (n > 0)
    {
        // Výstupní text = stávající výstupní text + "přetečení"
        s = s + " přetečení";
    }
 
    // Výstupní text je návratem metody
    return s;

}

Kód 2: Deklarace statické metody s textovým návratem s názvem Prevod