Registrovaný: 06 Jan 2012, 19:26 Príspevky: 458 Bydlisko: pod Pátrovom Udelené body:228 bodov Získané body:21 bodov
1. Napíš funkciu int dlzka_int(void), ktorá vráti dĺžku premennej typu int v bitoch. Zabezpeč, aby funkcia pracovala správne na ľubovoľnom type počítača. Vyskúšaj v programe.
Spoiler:
Kód:
/********************************** * 1.c v.1.0 * * Zistenie dlzky typu int v bitoch * ================================ * **********************************/
/* Vypocet poctu bytov za pomoci bitoveho posunu doprava z maximalneho cisla unsignad int sa budeme postupne posuvat do prava po jednom bite az po nulu, teda bity sa posuvaju a zlava stracaju, menia sa na nuly a vlastne dekadicke cisla sa postupne znizuju delenim dvomi */ printf("%2d. bit ->\tdec: %10u\t bin: %32s\n", i, x, des_dvoj_kr(x)); while ((x >>= 1) != 0) { // bitovy posun do prava i++; printf("%2d. bit ->\tdec: %10u\t bin: %32s\n", i, x, des_dvoj_kr(x)); } i += 1; printf("%2d. bit ->\tdec: %10u\t bin: %32s\n", i, x, des_dvoj_kr(x)); return (i); }
/* pomocna fánkcia na vypis binarneho cisla prevod z desiatkoveho na dvojkove, vystup dvojkove (retazec) */ char* des_dvoj_kr(unsigned int desiatkove) { int i = 0, j, k = -1; char *p_pom, *p_pom1, *p_dvojkove;
/* vypocet dvojkoveho cisla, prevod na retazec, jeho otocenie od zadu, doplnenie nul do celej dlzky dvojkoveho cisla */ while (desiatkove != 0) { // cyklus kym nebude 0 p_pom[i] = (desiatkove % 2) + 48; //zvysok po deleni 2 zmeneny na znak desiatkove /= 2; i++; // pom[i] sa zvacsuje s kazdym cyklom } p_pom[i] = '\0'; // ukoncenie retazca for (j = i; j >= 0; j--) p_pom1[j] = p_pom[k++]; // prepis od zadu p_pom1[i + 1] = '\0'; // ukoncenie retazca for (j = 0; j < VELKOST_INT - strlen(p_pom1); j++) // doplnenie nul do velkosti p_dvojkove[j] = '0'; // int minus velkost p_pom1 strcat(p_dvojkove, p_pom1); //spojenie retacov do jedneho bin cisla
return (p_dvojkove); }
2. Napíš funkciu unsigned rotuj_doprava(unsignet x, int n), ktorá spôsobí rotáciu (nie posun) čísla o n bitov doprava. Vyskúšaj v programe.
Spoiler:
Kód:
/*************************** * 2.c v.1.0 * * Rotacia bitov doprava * ========================= * * bity sa posuvaju do prava * a nulty bit sa presuva * na najvyssi bit * ***************************/
#define VELKOST_INT (sizeof(int) * 8) // pocet bitov v int, v mojom pripade 32
/* uplne funkcne prototypy funkcii */ unsigned rotuj_doprava(unsigned int x, int n); char* des_dvoj_kr(unsigned int desiatkove);
/* funkcia main */ int main(void) { unsigned cislo, i = 0;
cislo = 2147483648;
/******************************************************************** * vyskusaj si aj zadavanie cisiel, odkomentuj nasledujuce dva riadky * a zakomentuj riadok: cislo = 2147483648; ********************************************************************/ //printf("Zadaj kladne cislo. ktore chces rotovat do prava: "); //scanf("%u", &cislo);
printf("%u(d) %0*x(h) %32s(b)\n\n", cislo, sizeof(int) * 2, rotuj_doprava(cislo, i), des_dvoj_kr(rotuj_doprava(cislo, i))); /* vypise o kolko bitov je rotacia, dec cislo, hex cislo a bin cislo */ for (i = 0; i <= sizeof(int) * 8; i++) { printf("rotacia %2d bit: %10u(d) %0*x(h) %32s(b)\n", i, rotuj_doprava(cislo, i), sizeof(int) * 2, rotuj_doprava(cislo, i), des_dvoj_kr(rotuj_doprava(cislo, i))); }
return 0; }
/* rotuje bity doprava */ unsigned rotuj_doprava(unsigned int x, int n) { unsigned int i, k;
/* priprava jednotky v najvyssom bite */ /* do unsigned k vlozime same jednotky (negacia nuly) */ k = ~0; /* 4294967295(d) ffffffff(h) 11111111111111111111111111111111(b) */ /* na najvyssí bit dame nulu (posun doprava o jeden bit) */ k >>= 1; /* 2147483647(d) 7fffffff(h) 01111111111111111111111111111111(b) */ /* spravime negaciu, teda na najvyssom bite bude jednotka a dalej nuly */ k = ~k; /* 2147483648(d) 80000000(h) 10000000000000000000000000000000(b) */
while (n-- != 0) { i = x & 1; x >>= 1; x |= (i == 1) ? k : 0; }
return x; }
/* pomocna fánkcia na vypis binarneho cisla prevod z desiatkoveho na dvojkove, vystup dvojkove (retazec) */ char* des_dvoj_kr(unsigned int desiatkove) { int i = 0, j, k = -1; char *p_pom, *p_pom1, *p_dvojkove;
/* vypocet dvojkoveho cisla, prevod na retazec, jeho otocenie od zadu, doplnenie nul do celej dlzky dvojkoveho cisla */ while (desiatkove != 0) { // cyklus kym nebude 0 p_pom[i] = (desiatkove % 2) + 48; //zvysok po deleni 2 zmeneny na znak desiatkove /= 2; i++; // pom[i] sa zvacsuje s kazdym cyklom } p_pom[i] = '\0'; // ukoncenie retazca for (j = i; j >= 0; j--) p_pom1[j] = p_pom[k++]; // prepis od zadu p_pom1[i + 1] = '\0'; // ukoncenie retazca for (j = 0; j < VELKOST_INT - strlen(p_pom1); j++) // doplnenie nul do velkosti p_dvojkove[j] = '0'; // int minus velkost p_pom1 strcat(p_dvojkove, p_pom1); //spojenie retacov do jedneho bin cisla
return (p_dvojkove); }
3. Napíš funkciu unsigned invert(unsigned x, int p, int n), ktorá invertuje (zmení 1 za 0 a naopak) n bitov premennej x počnúc od pozície p vrátane. Ostatné bity ostanú nezmenené. Vyskúšaj v programe.
#define VELKOST_INT (sizeof(int) * 8) // pocet bitov v int, v mojom pripade 32
/* uplne funkcne prototypy funkcii */ unsigned invert(unsigned int x, int p, int n); char* des_dvoj_kr(unsigned int desiatkove);
/* funkcia main */ int main(void) { unsigned int cislo, i, j;
/* zadanie vstupnych dat */ printf("Zadaj unsigned int cislo: "); scanf("%u", &cislo); printf("Zadaj od ktorej pozicie sa maju bity invertovat: "); scanf("%u", &i); printf("Zadaj kolko bitov sa ma invertovat: "); scanf("%u", &j); /* vypis vystupov */ printf("\n%s\n", des_dvoj_kr(cislo)); // zadane cislo binarne printf("%s\n", des_dvoj_kr(invert(cislo, i, j))); // invert coslo binarne
return 0; }
/* invertuje skupinu zadanu bitov p = pozicia od, n = pocet invertovanych bitov */ unsigned invert(unsigned int x, int p, int n) { unsigned int i, k = x, j = p, l, m;
m = VELKOST_INT;
if (n <= m) { // aby pocet invertovanych bitov nebol vacsi ako velkost int if (n <= j) { // ak pocet bitov neprekroci pravy posledny bit i = j - n; // posledny bit na inverziu vpravo od pozicie while (j > i) { // od pozicie po posldeny bit na inverziu vravo k ^= (1 << j - 1); // negacia vyclenenych bitov j--; // krok } } else { while (j > 0) { // od pozicie po posldny bit vpravo (0) k ^= (1 << j - 1); // negacia vyclenenych bitov j--; // krok } l = m - (n - p); /* poradove cislo bitu potrebne pri prekroceni prveho praveho bitu a presunu na prvy lavy bit aby sme vedeli az pokial sa budu bity invertovat*/
while (m > l) { // od 1. bitu vlavo po l k ^= (1 << m - 1); // negacia vyclenenych bitov m--; // krok } } } else printf("Pocet invertovanych bitov mimo rozsah! Neinvertujem!\n");
return k; }
/* pomocna fánkcia na vypis binarneho cisla prevod z desiatkoveho na dvojkove, vystup dvojkove (retazec) */ char* des_dvoj_kr(unsigned int desiatkove) { int i = 0, j, k = -1; char *p_pom, *p_pom1, *p_dvojkove;
/* vypocet dvojkoveho cisla, prevod na retazec, jeho otocenie od zadu, doplnenie nul do celej dlzky dvojkoveho cisla */ while (desiatkove != 0) { // cyklus kym nebude 0 p_pom[i] = (desiatkove % 2) + 48; //zvysok po deleni 2 zmeneny na znak desiatkove /= 2; i++; // pom[i] sa zvacsuje s kazdym cyklom } p_pom[i] = '\0'; // ukoncenie retazca for (j = i; j >= 0; j--) p_pom1[j] = p_pom[k++]; // prepis od zadu p_pom1[i + 1] = '\0'; // ukoncenie retazca for (j = 0; j < VELKOST_INT - strlen(p_pom1); j++) // doplnenie nul do velkosti p_dvojkove[j] = '0'; // int minus velkost p_pom1 strcat(p_dvojkove, p_pom1); //spojenie retacov do jedneho bin cisla
return (p_dvojkove); }
4. Napíš program, ktorý bude využívať bitové pole na úschovu dátumu. Položky poľa budú:
bity 15 - 9 : rok, ku ktorému sa pripočíta konštanta 1980 teda 22 znamená v skutočnosti rok 2002 bity 8 - 5 : mesiac bity 4 - 0 : deň
Program vyskúšaj tak, že načítaš z klávesnice dátum, uložíš ho do bitového poľa, to vytlačíš ako typ unsigned a potom dátum vytlačí ako naozajstný dátum. Na vytlačenie premennej ako unsigned použi union.
Spoiler:
Kód:
/****************************************************** * 4.c v.1.0 * * Bitove pole - pouzitie pro ulozenie zhusteneho cisla * ==================================================== * ******************************************************/
typedef union { DATUM datum; // deklarovana premenna typu DATUM unsigned int cislo; // deklarovana premenna typu unsigned int } BITY; // deklarovany union typ
int main(void) { BITY dnes; // deklarovana premenna typu BITY unsigned int den, mesiac, rok;
printf("Zadaj dnesni datum [dd.mm.rrrr]: "); scanf("%d.%d.%d", &den, &mesiac, &rok); dnes.datum.den = den; dnes.datum.mesiac = mesiac; dnes.datum.rok = rok - 2000; // rok dnesneho datumu je nad 2000 //printf("Premenna ako unsigned int je %u\t%s\n", dnes, des_dvoj_kr((unsigned int) dnes)); printf("Premenna ako unsigned int je %u\n\n", dnes); printf("Dnesny datum je %2u.%2u.%4u\n\n", dnes.datum.den, dnes.datum.mesiac, dnes.datum.rok + 2000);
_________________ kódy píšem na platforme: linux Ubuntu 12.04 (Geany, Code::Blocks), WinXP (Code::Blocks, PsPad editor), Skype: libcokamo, ICQ: 56312279 Ak treba, napíš mi na libcosenior@gmail.com. To mám v mobile a stále po ruke.
Užívatelia prezerajúci fórum: Žiadny registrovaný užívateľ nie je prítomný a 1 hosť
Nemôžete zakladať nové témy v tomto fóre Nemôžete odpovedať na témy v tomto fóre Nemôžete upravovať svoje príspevky v tomto fóre Nemôžete mazať svoje príspevky v tomto fóre Nemôžete zasielať súbory v tomto fóre