Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: webhope 10. 01. 2014, 15:23:42

Název: Můžete mi vysvětlit výpočet?
Přispěvatel: webhope 10. 01. 2014, 15:23:42
Narazil jsem na jeden kód matematický vzorec v kódu (php) a nemůžu pochopit jak to funguje.
Funkce má několik vstupních proměnných, ke vzorci se vztahuje $fld_acs, což je přirozené číslo.
Proměnná global se vyskytuje ve tvou variacích. Zde uvádím jen tu první variaci, tu druhou se mi už nechtělo počítat. fld_acs nějakým způsobem určuje přístup k poli (jestli se proměnná bude zobrazovat či nikoliv na výstupu).
vzorec:

Kód: [Vybrat]
$bool =  $global & pow(2,$fld_acs); 
Moje propočty:
Kód: [Vybrat]
2146413821 & 2^0 = 2146413821 & 1 = 1
2146413821 & 2^2 = 2146413821 & 4 = 4
2146413821 & 2^3 = 2146413821 & 8 = 8
2146413821 & 2^4 = 2146413821 & 16 = 16
2146413821 & 2^5 = 2146413821 & 16 = 32
2146413821 & 2^6 = 2146413821 & 32 = 64
2146413821 & 2^7 = 2146413821 & 128 = 128
2146413821 & 2^8 = 2146413821 & 256 = 0
2146413821 & 2^9 = 2146413821 & 512 = 0
2146413821 & 2^10 = 2146413821 & 1024 = 1024
2146413821 & 2^11 = 2146413821 & 2048 = 2048
2146413821 & 2^12 = 2146413821 & 4096 = 0
2146413821 & 2^13 = 2146413821 & 8192 = 8192
2146413821 & 2^14 = 2146413821 & 16384 = 0
2146413821 & 2^15 = 2146413821 & 524288 = 524288
2146413821 & 2^16 = 2146413821 & 1048576 = 1048576
2146413821 & 2^17 = 2146413821 & 2097152 = 2097152
2146413821 & 2^18 = 2146413821 & 2097152 = 4194304
2146413821 & 2^28 = 2146413821 & 8 = 268435456

Jelikož nechápu jak funguje operátor & tak mi není jasné proč je někdy výsledek 0. Vysvětlí někdo?
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: 3ugeene 10. 01. 2014, 15:26:17
and je logický součin - pokud jsou bity na stejných pozicích v obou číslech 1, bit výsledku na dané pozici je taky 1
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: none_ 10. 01. 2014, 15:42:53
Kód: [Vybrat]
$bool =  $global & pow(2,$fld_acs); 
Moje propočty:
Kód: [Vybrat]
2146413821 & 2^0 = 2146413821 & 1 = 1111111111011111010110011111101 & 1 = 1
2146413821 & 2^2 = 2146413821 & 4 = 1111111111011111010110011111101 & 100 = 100 = 4
2146413821 & 2^3 = 2146413821 & 8 = 1111111111011111010110011111101 & 1000 = 8
2146413821 & 2^4 = 2146413821 & 16 = ... = 16
2146413821 & 2^5 = 2146413821 & 16 = 32
2146413821 & 2^6 = 2146413821 & 32 = 64
2146413821 & 2^7 = 2146413821 & 128 = 128
2146413821 & 2^8 = 2146413821 & 256 = 1111111111011111010110_0_11111101 & 1_00000000 = 0
2146413821 & 2^9 = 2146413821 & 512 = 111111111101111101011_0_011111101 & 1_000000000 = 0
2146413821 & 2^10 = 2146413821 & 1024 = 11111111110111110101_1_0011111101 & 1_0000000000 = 1024
2146413821 & 2^11 = 2146413821 & 2048 = 2048
2146413821 & 2^12 = 2146413821 & 4096 = 0
2146413821 & 2^13 = 2146413821 & 8192 = 8192
2146413821 & 2^14 = 2146413821 & 16384 = 0
2146413821 & 2^15 = 2146413821 & 524288 = 524288
2146413821 & 2^16 = 2146413821 & 1048576 = 1048576
2146413821 & 2^17 = 2146413821 & 2097152 = 2097152
2146413821 & 2^18 = 2146413821 & 2097152 = 4194304
2146413821 & 2^28 = 2146413821 & 8 = 268435456

Atd atd... Jen nevim, k čemu je to dobrý...:D
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: Ziktofel 10. 01. 2014, 15:45:10
jo, todle jsem videl, kdyz se v nejakym systemu nastavujou opravneni, prava jednoho uzivatele pak zapises jako jeden int

prava maj ID 0-31

a pak muzes definovat neco takovyho:

function hasAccess($access_where){
  return $this->access & 2^$acess_where !=false;
}


jinak tydle operaci se rika and po bitech
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: Ziktofel 10. 01. 2014, 15:46:39
jo, misto toho ^ ma bejt pow(2, $access_where) uz blbnu, ^ je zase xor po bitech
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: none_ 10. 01. 2014, 15:48:13
Jo hezký příklad.:) Díky...
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: Ziktofel 10. 01. 2014, 15:49:44
jinak obvykle na to narazis asi tam, kde mas pole booleanu a potrebujes ho napsat jako jeden int (coz se muze hodit treba pro ulozeni do db)
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: Ziktofel 10. 01. 2014, 15:56:44
a jeste lip se da misto umocnovani pouzit bitovej posun doleva (1<<$access_where)
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: webhope 10. 01. 2014, 15:59:19
none_: z těch prvních tří řádků jsem to nepochopil (to by chtělo barevně zobrazit ten konktrétní bit) ale  u těch násobků 256, 512 a 1024 už jsem to pochopil. Takže jde o to hledat ten jeden konkrétní bit, první bit čísla kterým násobím...

Ten zbytek - to využití, tak nad tím ještě musím přemýšlet. Taky to nechápu.
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: webhope 10. 01. 2014, 16:09:15
Ziktofel:
Citace
jinak obvykle na to narazis asi tam, kde mas pole booleanu a potrebujes ho napsat jako jeden int (coz se muze hodit treba pro ulozeni do db)
Nad něčím takovým jsem uvažoval, že bych to mohl udělat, a říkal jsem si jestli by to šlo pak použít pro "vyhledávač" (do html formuláře zadáš konkrétní bolean hodnoty pomocí input checkbox, a pak bych provedl nějakou operaci, která by tu boolean hodnotu vytáhla (např. z mysql databáze nebo z datového souboru). Ale nevím jak se takové věci (bitové porovnávání) dělají v praxi. Takže registrovaní uživatelé s id 0, 1, 2, 3 si uloží 4 volby v nastavení v hodnotách např 1001 (první uživatel),  1101, 0100, 0101 (poslední uživatel). A pak chci hledat nějakého uživatele, který má první a třetí bit zapnutý (nebo naopak, první nebo třetí)... tak jak to udělat... To by mě taky zajímalo.
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: none_ 10. 01. 2014, 16:10:38
No nemusí to být jen první bit. Záleží na těch konkrétních číslech. Prostě když se potkají na stejné pozici jedničky, tak je opíšeš. Jinak píšeš nulu. Nakonec číslo převedeš zase zpátky do desítkový.

Každopádně v tvém případě jsou to asi všude jen mocniny dvou a pak opravdu záleží jen na první 1.
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: none_ 10. 01. 2014, 16:18:18
no podle predchoziho vzorce od Zikofela je to jednoduchý.
Nadefinuješ role:
2^0 = 1 == můžu na stránku
2^1 = 10  == můžu psát komentáře
2^2 = 100  == můžu přidávat články
...

pak nadefinuješ pro konkrétního uživatele oprávnění.
např:
101 = 5 a to uložíš do DB.

Uživatel příjde a chceš vědět, jestli může na stránku, tak zavoláš tenhle vzorec pro hodnoty:
$bool =  $global & pow(2,$fld_acs);
$global = 101 - oprávnění uživatele
$fl_asc = 2 - např

--> $bool = 101 & pow(2,2) = 101 & 100 = 100 = 4

Pokud $bool == 0, tak nemá oprávnění. Jinak .
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: none_ 10. 01. 2014, 16:19:08
ps: role mají čísla 0, 1, 2, 3, 4,...
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: webhope 10. 01. 2014, 16:37:58
none_: Ta první věc co se týká přístupu kde nastavuješ On/Off jako binární 1 nebo 0, to už chápu.
Ale, když jsem tak o tom přemýšlel, tak mě napadlo co tedy znamená ten základ v pow? násobím číslo dva. Znamená to dva možné stavy? Mám dva stavy, takže kdybych měl stavy tři budu násobit číslo 3? A pokud ano, bylo by nutné mít toto pole, kde jsou uložené přístupy mít vše ve stejném rozměru? Pokud příjmu předpoklad, že potřebuji tři stavy, vytvořil bych pole
0,1,2,3,4 ... kde ale každý prvek pole má tři bity. Tedy první prvek má 0000,0001,0010, druhý má 0011, 0100, 0101, třetí má 0110, 0111, 1000, atd. jestli jsem nic nevynechal... Pak by první role pro všechny tři byla rovna 0000, 0011, 0110 ... ; druhá role by byla rovna 0001, 0100, 0111, a poslední role by byla rovna 0010, 0101, 0111 , ovšem nepočítalo by se to tak snadno jako u základu 2. A já nevím třeba je tento můj předpoklad úplně špatný...
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: Mr. Curious 10. 01. 2014, 16:55:22
Ja jsem vedel, ze je to s programatory v PHP zle. Jen jsem netusil, ze az tak moc ...
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: none_ 10. 01. 2014, 17:06:19
ee, ten tvůj předpoklad je špatně. Ta dvojka je tam kvůli tomu, že v binární soustavě se počítá vždycky s mocninami dvou a víš, že když dáš 2 na nějaký číslo, tak ti vyjde číslo, který bude mít v binární soustavě jedničku a pak samý nuly. Takže podle toho hledá, jestli na X pozici (počítáno od 0) je 1.

Je na druhé (počítáno od nuly) pozici čísla 1000100 jednička?
$bool = 1000100 & pow(2,2) = 1000100 & 100(to je 4) = 100 = 4
takže $bool > 0 --> ano, na druhé pozici je 1.

Tři stavy tady u toho nikdy mít nemůžeš, protože binární čísla znají jen 0 nebo 1. Tzn. buď zapnuto nebo vypnuto nějaké oprávnění. Každopádně pokud potřebuješ nějaké specifičtější oprávnění např: může editovat stránku a zároveň může všechno číst, tak se může dotazovat na dvě pozice a povolit aby něco udělal jen, když bude mít na obou pozicích 1.

Obecně takhle můžeš uložit jen věci typu true/false, popřípadě true/false && true/false, ale to už psal Ziktofel...:)
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: none_ 10. 01. 2014, 17:11:51
Popřípadě, pokud opravdu potřebuješ pro něco 3 stavy (což nebude asi ale případ u oprávnění), tak musíš použít něco jiného. Nějakou složitější strukturu. Teoreticky bys mohl použít trojkovou soustavu a pak by ty čísla vypadala třeba takhle: 21020120221. Ale to už mi přijde jako dobrej guláš a hrozí, že za týden narazíš na problém, že potřebuješ 4 stavy a budeš tam, kdes byl předtím.
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: j 10. 01. 2014, 17:31:36
Obecne se na vice stavu pouzije vice bitu ...

Jinak se celymu postupu rika taky maskovani.

10001001 .... je rekneme hodnota, zajimaj me bity 2,4,5 =>
00110100 ... je maska

A ted uz se na to postve jen spravna logicka operace, v zavislosti na tom, jaky vysledek hledam. Trebas pokud na to postvu AND .. tak zjistim, ze ani jeden z pozadovanych bitu neni nastaven => vysledek je 0 => false.
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: Petr 10. 01. 2014, 18:27:41
Popřípadě, pokud opravdu potřebuješ pro něco 3 stavy (což nebude asi ale případ u oprávnění), tak musíš použít něco jiného. Nějakou složitější strukturu. Teoreticky bys mohl použít trojkovou soustavu a pak by ty čísla vypadala třeba takhle: 21020120221. Ale to už mi přijde jako dobrej guláš a hrozí, že za týden narazíš na problém, že potřebuješ 4 stavy a budeš tam, kdes byl předtím.
z techto duvodu je lepsi volit soustavu o zakladu alespon 50 :) Ano, uz to potom sice nenarves do integeru, ale i tak - na definici pristupovych prav k objektu potom staci bohate nejakej varchar(8) - s tim, ze muzes samozrejme pouzivat i skupiny, namisto jednotlivych uzivatelu (staci pridat bitovy flag).
Ackoliv mi tahle technika prisla dost obskurni, tak je dost efektivni a na zadnej lepsi zbusob, jak ukladat usporne ACL do DB jsem neprisel :o
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: Lol Phirae 10. 01. 2014, 18:31:59
Pokud si projdeš kód phpBB, tak tam pokud si dobře pamatuju používají podobnou šílenost.
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: webhope 10. 01. 2014, 18:38:25
Už mi to začíná být jasný  :) Takže i když jsou nebo budou ty volby uložené pod nějakým desítkovým číslem, tak si to nejdříve musím převést na binární číslo a provést binární operaci, nebo to mohu provést pomocí binárního násobení ... o & pow(2,y) ...

Otázka ale je: v jakém směru čtete ty pozice, zleva doprava nebo zprava doleva :) ? Já to čtu zprava doleva.

Petr: Na termín ACL jsem tam taky narazil. No vida.

Lol Phirae: PHPBB nepoužívám, ale třeba někdy v budoucnu se na to podívám.
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: cik951 10. 01. 2014, 18:49:22
Ziktofel:
Citace
jinak obvykle na to narazis asi tam, kde mas pole booleanu a potrebujes ho napsat jako jeden int (coz se muze hodit treba pro ulozeni do db)
Nad něčím takovým jsem uvažoval, že bych to mohl udělat, a říkal jsem si jestli by to šlo pak použít pro "vyhledávač" (do html formuláře zadáš konkrétní bolean hodnoty pomocí input checkbox, a pak bych provedl nějakou operaci, která by tu boolean hodnotu vytáhla (např. z mysql databáze nebo z datového souboru). Ale nevím jak se takové věci (bitové porovnávání) dělají v praxi. Takže registrovaní uživatelé s id 0, 1, 2, 3 si uloží 4 volby v nastavení v hodnotách např 1001 (první uživatel),  1101, 0100, 0101 (poslední uživatel). A pak chci hledat nějakého uživatele, který má první a třetí bit zapnutý (nebo naopak, první nebo třetí)... tak jak to udělat... To by mě taky zajímalo.
Jestli můžu doporučit, tak se podívej nejprve na to,
Nemyslím to nijak ironicky, ale určitě se ti to bude hodit. Tak například pokud hledáš uživatele, který má "zapnutý první a třetí bit", tak to uděláš pomocí bitového součinu s číslem 0b101 ( PHP 5.4+ )
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: cik951 10. 01. 2014, 19:02:26
Citace
, který má "zapnutý první a třetí bit",
Taky bych si to mohl přečíst než to pošlu  ::)  To měla být ta druhá varianta "zapnutý první nebo třetí bit"
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: Tomix nologin 11. 01. 2014, 08:30:33
Citace
Taky bych si to mohl přečíst než to pošlu  ::)  To měla být ta druhá varianta "zapnutý první nebo třetí bit"

Není to spíš nultý a druhý?
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: Radovan. 11. 01. 2014, 10:08:51
Takže i když jsou nebo budou ty volby uložené pod nějakým desítkovým číslem, tak si to nejdříve musím převést na binární číslo ...
Ale nemusíš, ty už to v počítači převedené máš, protože jinou než dvojkovou soustavu ta "relátka" neumějí ;-)

Jinak už je příklad výš, jen ho trochu doplním:
10001001 .... je rekneme hodnota, zajimaj me bity 2,4,5 =>
00110100 ... je maska
---------------------------
00000000 ... je výsledek, protože při & (AND neboli logický součin) jednička vyjde jen tam, jde jsou bity v obou číslech jedničkové


A v jiném případě:
10001001 .... je stejná hodnota, zajímají mě tentokrát nejnižší čtyři bity, tedy 0 až 3 =>
00001111 ... je maska
---------------------------
00001001 ... je výsledek, který si můžeš klidně z hlavy převést na desítkové číslo: 8+1=9


Bity neboli dvojkové číslice se berou ve stejném pořadí jako ty naše desítkové, tedy s nejnižší hodnotou vpravo.

Ještě bys tam mohl mít |, neboli OR - logický součet, který dá jedničku tam, kde je aspoň jeden z bitů obou čísel jednička:
10001001 .... je zase stejná hodnota, zajímají mě opět nejnižší čtyři bity, tedy 0 až 3 =>
00001111 ... je stejná maska
---------------------------
10001111 ... a výsledek si stejně snadno jako v minulém případě převedeš z hlavy na desítkové číslo: 128+8+4+2+1=143


Ještě poznámka o tom proč se bity číslují (zprava) 0 až 7, je to proto že jejich hodnota odpovídá příslušné mocnině dvojky:
27 = 128
26 = 64
25 = 32
24 = 16
23 = 8
22 = 4
21 = 2
20 = 1

A u dvaatřicetibitového čísla bys takhle samozřejmě pokračoval až do 231.
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: webhope 11. 01. 2014, 11:24:15
Díky všem, kromě pana Curiouse, za pomoc. Už to chápu a používám to ve své nové metodě. Je to geniální.
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: turista- 11. 01. 2014, 12:02:55
Jistě, že to je geniální. Když programátor objeví bitové operace, je to jako když mechanik objeví šroubovák.
Název: Re:Můžete mi vysvětlit výpočet?
Přispěvatel: webhope 12. 01. 2014, 10:13:44
turista: nejsem programátor, jsem jen turista  ;D