Advertisement
Guest User

Untitled

a guest
Mar 18th, 2019
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.28 KB | None | 0 0
  1. // enum.c
  2. // Řešení IJC-DU1, příklad a), 20.3.2111
  3. // Autor: Jároslav Cimrman, FIT
  4. // Přeloženo: gcc 8.2
  5. // ...popis příkladu - poznámky, atd
  6.  
  7. #include <limits.h>
  8. #include "error.h"
  9. #include <assert.h>
  10.  
  11. #ifndef IJC_LIBRARY_H
  12. #define IJC_LIBRARY_H 1
  13.  
  14. #define Bi_Me (sizeof(unsigned long)*__CHAR_BIT__)
  15.  
  16. typedef unsigned long *bit_array_t;
  17.  
  18. //Velikost pole, odečtením 1L se mohu spolehnout, že po zprůměrování budou dva longy navíc stačit.
  19. //Na uložení velikosti v prvním bloku + pro přesah do dalšího bloku, po celočíselném dělení)
  20. #define SIZE(velikost) ((velikost/Bi_Me) + ((velikost%Bi_Me) ? 2L : 1L))
  21.  
  22. //Určení pozice jedničky v masce. Budu se posouvat zprava doleva, tedy jdu druhou stranou, než jak jdu v poli.
  23. #define post(index) (index%Bi_Me)
  24.  
  25. //Určení správného bloku v poli. Je tvořeno unsigned longy, každý má osm bitů. Podle hodnoty indexu se posouvám po celých blocích.
  26. //Indexace jde od nuly, proto poslední bit má index "počet prvnků v poli" -1. První blok v poli je vynechán, drží hodnotu s velikostí pole.
  27. #define INX(jmeno_pole, index) ((SIZE(jmeno_pole[0]) - (index/Bi_Me)) - 1L)
  28.  
  29. #define bit_array_create(jmeno_pole, velikost) unsigned long jmeno_pole[SIZE(velikost)] = {(velikost)};\
  30. _Static_assert((velikost) > 0 && (velikost) < (ULONG_MAX), "bit_array_create: Chybně zadaná velikost pole.\n");
  31.  
  32. #define bit_array_alloc(jmeno_pole, velikost) assert((velikost) > 0 && (velikost) < (ULONG_MAX)); bit_array_t (jmeno_pole) = calloc(SIZE((velikost), Bi_Me));\
  33. if((jmeno_pole) == NULL) {bit_array_free(jmeno_pole); error_exit("bit_array_alloc: Chyba alokace paměti.\n");} (jmeno_pole[0]) = (velikost);
  34.  
  35. #define bit_array_free(jmeno_pole) free((jmeno_pole))
  36.  
  37. //Pomocné makro k funkci bit_array_setbit, po splnění podmínky rozsahu nastaví hodnotu v "jmeno_pole" na místě označené "index" na hodnotu "výraz"
  38. // Indexace probíhá od nuly. Správný blok a index v poli poskytují příslušná makra.
  39. #define bit_array_setbit_pom(jmeno_pole, index, vyraz) ((vyraz!=0) ? (jmeno_pole[INX(jmeno_pole, index)] |= (1L << post(index))) : \
  40. (((jmeno_pole)[INX(jmeno_pole, index)]) &= ~(1L << post(index))))
  41.  
  42. //Pomocné makro k funkci bit_array_getbit, po splnění podmínky rozsahu vrátí hodnotu v "jmeno_pole" na místě označeném "index". Vrací hodnuty nula nebo jedna.
  43. //Indexace probíhá od nuly. Správný blok a index v poli poskytují příslušná makra.
  44. #define bit_array_getbit_pom(jmeno_pole, index) (((unsigned long)(jmeno_pole)[INX(jmeno_pole, index)]) & (1L << post(index)) ? 1 : 0)
  45.  
  46. //Konec maker
  47.  
  48. #ifndef USE_INLINE
  49. #define bit_array_size(jmeno_pole) (unsigned long)(jmeno_pole[0])
  50.  
  51. #define bit_array_getbit(jmeno_pole, index) ((index) < (((jmeno_pole)[0]/Bi_Me) + ((jmeno_pole)[0]%Bi_Me) ? 1 : 0)) ? (bit_array_getbit_pom((jmeno_pole), (index))):\
  52. (error_exit("bit_array_getbit: Index %lu mimo rozsah 0..%lu", (unsigned long)(index), (unsigned long)bit_array_size(jmeno_pole)), -1)
  53.  
  54. #define bit_array_setbit(jmeno_pole, index, vyraz) ((index) < (((jmeno_pole)[0]/Bi_Me) + ((jmeno_pole)[0]%Bi_Me) ? 1 : 0)) ? (bit_array_setbit_pom((jmeno_pole), (index), (vyraz))):\
  55. ((error_exit("bit_array_getbit: Index %lu mimo rozsah 0..%lu", (unsigned long)(index), (unsigned long)bit_array_size(jmeno_pole)), -1)))
  56.  
  57. //Konec inline funkcí
  58.  
  59. #else
  60. inline int bit_array_getbit(bit_array_t jmeno_pole, unsigned long index){
  61. if(index+1 > jmeno_pole[0]){
  62. (error_exit("bit_array_getbit: Index %lu mimo rozsah 0..%lu",(unsigned long)index, (unsigned long)jmeno_pole[0]));
  63. return -1; //Vyletí už na error_exit
  64. }
  65. else{ return bit_array_getbit_pom(jmeno_pole, index); }
  66. }
  67.  
  68. inline void bit_array_setbit(bit_array_t jmeno_pole, unsigned long index, int vyraz){
  69. if(index+1 > jmeno_pole[0]){
  70. (error_exit("bit_array_getbit: Index %lu mimo rozsah 0..%lu", (unsigned long)index, (unsigned long)jmeno_pole[0]));
  71. return;
  72. }
  73. else{ bit_array_setbit_pom(jmeno_pole, index, vyraz); }
  74. }
  75.  
  76. inline unsigned long bit_array_size(bit_array_t jmeno_pole)
  77. {
  78. return (unsigned long)jmeno_pole[0];
  79. }
  80.  
  81. #endif //Konec USE_INLINE
  82. #endif //Konec IJC_LIBRARY_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement