Jak zjistit počet bitů? – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Jak zjistit počet bitů? – C / C++ – Fórum – Programujte.comJak zjistit počet bitů? – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
oxidián0
Věrný člen
16. 3. 2015   #1
-
0
-

Dá se nějak efektivně vypočítat počet nulových bitů v čísle zleva? Aniž by člověk musel používat smyčky a převody pomocí *char. Existuje na to nějaký trik? V tabulce níže jsou uvedené číselné rozsahy, lichý řádek minimum, sudý maximum. Jde o 32 bitové číslo, ale pro jednoduchost jsem ty nuly nedopsal.  Tak např. první dva řádky mají mít 30 nul zleva. Jako další příklad uvedu uint32_t x=0b100010 ... číslo se nachází ve druhém rozsahu a má mít 26 nul. Jaksi mě zajímá jestli existuje nějaká finta jak vrátit řád ve kterém se to nachází.

                      10  0x02        0
                      10  0x02        0
                    1000  0x08        1
                    1000  0x08        1
                  100000  0x20        2
                  100110  0x26        2
                10000000  0x80        3
                10011011  0x9B        3
              1000000000  0x200       4
              1001101111  0x26F       4
            100000000000  0x800       5
            100110111111  0x9BF       5
          10000000000000  0x2000      6
          10011011111111  0x26FF      6
        1000000000000000  0x8000      7
        1001101111111111  0x9BFF      7
      100000000000000000  0x20000     8
      100110111111111111  0x26FFF     8
    10000000000000000000  0x80000000  9
    10011011111111111111  0x9BFFF     9    
  1000000000000000000000  0x200000    10
  1001101111111111111111  0x26FFFF    10
100000000000000000000000  0x800000    11
100110111111111111111111  0x9BFFFF    11

A na co to potřebuju. Abych nemusel procházet celkem 15 rozsahů pomocí podmínek if ..else .. tak že bych prostě spočítal počet nul.

Nahlásit jako SPAM
IP: 78.45.199.–
Reklama
Reklama
KIIV+42
God of flame
16. 3. 2015   #2
-
0
-

Proc pomoci if else? Mame prece bitovy posun a cyklus.

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
PiranhaGreg0
Stálý člen
16. 3. 2015   #3
-
+1
-
Zajímavé

Jestli tě správně chápu, tak logaritmus je tvůj kamarád  . 

#include <stdio.h>
#include <math.h>
#include <limits.h>

const intSize = CHAR_BIT * sizeof(int);

int main(void) {
	int cislo = 1020;

	int result = intSize - (int)log2(cislo);

	printf("%d\n", result);
	return 0;
}
Nahlásit jako SPAM
IP: 195.113.241.–
hlucheucho+10
Posthunter
16. 3. 2015   #4
-
0
-

#2 KIIV
cyklus se mu asi nebude líbit   . A rekurze mu nebude dost efektivní. Pak bude každá rada drahá.   

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:5563:57...–
oxidián0
Věrný člen
16. 3. 2015   #5
-
0
-

#3 PiranhaGreg
Dík, myslím že tu funguje, ale že to tiskne výsledek o jedna větší:

int cislo = 0b10;

dává 31, a mělo by být 30. Tak asi výsledek zmenšit o jedna.

A napadla mě ještě další možnost, delší kód, ale možná (?) efektivnější, vytvořit 16 podmínek if .. else, kde každá testuje danou proměnnou s maskou. Takže test na první masku by byl třeba takto:

( cislo & ~0x11111111111111111111111111111100 )

přičemž by to mělo zjišťovat jestli se zam nachází 30 nul vlevo a další dva bity nerozhodují.

Pak udělat další podmnku a posunout o dva bity

( cislo & ~0x11111111111111111111111111110000 )

ale toto dělám nejspíš špatně páč to nefunguje.

Nahlásit jako SPAM
IP: 78.45.199.–
Satik0
Stálý člen
16. 3. 2015   #6
-
0
-

Nejrychlejší je použít asm instrukci bsr, která je k tomu určená :).

Nahlásit jako SPAM
IP: 86.49.188.–
oxidián0
Věrný člen
16. 3. 2015   #7
-
0
-

A to by bylo složité? O asm nic nevím, neumím

Nahlásit jako SPAM
IP: 78.45.199.–
PiranhaGreg0
Stálý člen
16. 3. 2015   #8
-
0
-

Stačí volat funkci 

int __builtin_clz (unsigned int x)

Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined.

Ale je to pouze pro gcc... Upřímně řešíš kraviny ;-). 

Nahlásit jako SPAM
IP: 195.113.241.–
Satik0
Stálý člen
16. 3. 2015   #9
-
0
-

 Třeba tohle (pro VS).

int cislo = 12345;
int bitCount = 0;

__asm
  {
    mov eax, cislo;
    bsr eax, eax;
    mov bitCount, eax;
  }
Nahlásit jako SPAM
IP: 86.49.188.–
oxidián0
Věrný člen
16. 3. 2015   #10
-
0
-

Tak jo, ta instrukce je skvělá. Smyčka 4000x4000 trvala 0.03s, logarismus trvá 0.35s

Vím že řeším kraviny, ale radši použiju tu rychlejší variantu přeci jen. Díky všem

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Věrný člen
16. 3. 2015   #11
-
0
-

#9 Satik
To mi hází

error: expected '(' before '{' token|

Není třeba něco includovat?

Nahlásit jako SPAM
IP: 78.45.199.–
PiranhaGreg0
Stálý člen
16. 3. 2015   #12
-
0
-
Nahlásit jako SPAM
IP: 195.113.241.–
Satik0
Stálý člen
16. 3. 2015   #13
-
0
-

#11 oxidián
To byl asm kód pro Visual Studio, musíš si zjistit, jak se asm zapisuje pro tvůj kompilátor.

Jinak to Gregovo řešení s největší pravděpodobností právě používá tu instrukci, takže to nemusíš řešit přes asm ;) 

Nahlásit jako SPAM
IP: 86.49.188.–
oxidián0
Věrný člen
16. 3. 2015   #14
-
0
-

Já nemám VS a píšu v C. VS ani nenainstaluju. Pokud to nejde do C tak asi nemá smysl abych se na to díval.

Nahlásit jako SPAM
IP: 78.45.199.–
hlucheucho+10
Posthunter
16. 3. 2015   #15
-
0
-

"Mixing C and asm code" hledej pro tvůj překladač. Nedávno ses tu vytahoval, jak umíš používat Google, tak ho použij!!

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:5563:57...–
oxidián0
Věrný člen
16. 3. 2015   #16
-
0
-

Zatím mi to ale stačí, dík

Nahlásit jako SPAM
IP: 78.45.199.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 62 hostů

Podobná vlákna

Jak zjistit jmeno PC? — založil machis

Jak zjistit IP adrsu PC — založil machis

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý