Ganze Zahl aufrunden zu 2er-Potenz



  • Hi,

    ich muss eine pos. Ganzzahl auf die nächste Potenz zur Basis 2 runden, wenn sie keine 2er-Potenz bereits darstellt.

    Geschrieben hab ich das erstmal:
    Also erst wird Logarithmus zur Basis 2 errechnet und, wenn er keine ganze Zahl ist, durch ceil aufgerundet.
    Und dann die neue Potenzzahl errechnet mit pow(2, expo);

    Size = pow(2.0f, (int)ceil(((double)log((double)Size)/log(2.0f))));
    

    Nicht wirklich schön 😞
    Irgendwie vermute ich doch mal stark, dass das irgendwie sauberer geht.
    Also ohne die ganzen Zwangskonvertierungen.

    Ich hab auch schon überlegt, das mit einer Schleife abzufragen und zu schauen, ob nach dem größten Bit noch weitere kommen.

    Aber vielleicht gibs ja doch eine simple Funktion oder Algo., die ich übersehen hab.



  • zb die zahl solange durch 2 rechnen bis sie kleiner 2 ist dabei einen integer mitlauifen lassen von 1 an

    und dann hat man 2^integer nexte 2erpotenz

    edit:

    wenn gleich 2 dann 2^(integer-1)



  • SeppSchrot schrieb:

    Ich hab auch schon überlegt, das mit einer Schleife abzufragen und zu schauen, ob nach dem größten Bit noch weitere kommen.

    so ähnlich, nach dem höchsten gesetzten bit löschte alle weg (nächst kleinere zweierpotenz) und dann alles einmal links shiften (die nächste grössere)



  • das problem hatte ich leztens auch brauchte ich für nen ezw-encoder/decoder...

    habs so gemacht

    size_t next2pow(size_t num){
    	size_t i;
    	if(!num)return 1;
    	for(i=8*sizeof(size_t)-1;!(num&(1<<i));--i);
    	if(num&((1<<i)-1))++i;
    	return 1<<i;
    
    }
    


  • int fkt(float n,int k)
    {
    if(n>2)
      ftk(n/2,k++);
    if(n==2)
      return k-1;
    if(n<2)
      return k;
    }
    


  • Ach du lieber Schreck Windalf 😉 Da bleib ich dann doch lieber bei meinem Einzeiler. 🤡
    Naja, hatte nur vermutet, ich hätt was übersehen, weil das Problem so einfach wär.

    Doch danke für eure Vorschläge.

    In lookias´ Algo steckt Kapital*, den werde ich morgen mal mit "? :" bearbeiten.

    * Ich versteh ihn nur noch nicht. 😉
    Naja, mal Blatt und Stift rauskram.



  • @SeppSchrot
    Seh gerad du bist ja auch Berliner (gruss aus Spandau... 😉 )

    hmm eigentlich hab ich doch genau das gemacht was du vorher erzählt hast

    Ich hab auch schon überlegt, das mit einer Schleife abzufragen und zu schauen, ob nach dem größten Bit noch weitere kommen

    genau das war jedenfalls auch meine intention dabei... 😃



  • oh das liegt daran dass zwischen einer zahl und seinem doppelten immer genau eine soclche potenz von 2 steckt
    halbiert man die zahl bis man unter 2 liegt so hat man die potenz der nexten 2er potenz der zahl

    nur ist ja die 2er potenz um einen hoeher dann sonst waere man nicht unter 2

    da man bei 1 anfaengt ist sie dann um eins niedriger wenn man bei 2 landet

    aber das ganze gelingt vlt nicht bis zur maximalen float zahl

    weil vielleicht schon auf 1 gerundet wird bei 4 millarden

    btw was isn "?:" ?



  • Dafür eine Rekursion an den Start zu bringen, halte ich für Overkill.

    unsigned int nextpoweroftwo(unsigned int n)
    {
    	int i=0;
    	for(;n;++i,n>>=1);
    	return 1 << i;
    }
    

    lookias schrieb:

    btw was isn "?:" ?

    Jaja, mit Satzzeichen hast du's ja offenbar nicht 😉



  • jo die lösung von MFK sieht am besten aus... was du dir noch überlegen musst ist ob du im falle einer zweierpotenz auch wirklich die nächste haben willst oder die zahl selber... indem fall dann noch 1 abziehen...



  • erklaehr mal bitte:

    return 1 << i;
    
    for(;n;++i,n>>=1);
    

    dat sieht mir irgendwie neu aus besonders das << kenn ich nur von cout
    (bzw >> von cin)
    und ;n ist doch best ein schreibfehler oder?



  • lookias schrieb:

    dat sieht mir irgendwie neu aus besonders das << kenn ich nur von cout

    Das ist der Shift-Operator, danach kann man besser googeln als nach "<<" 😉

    und ;n ist doch best ein schreibfehler oder?

    Nein, er will wohl nichts initialisieren.



  • lookias schrieb:

    erklaehr mal bitte:

    Solange deine Beiträge so schlecht zu lesen sind, nein. Bitte benutz Satzzeichen und vielleicht sogar Großbuchstaben, lass solche Sachen wie "dat" und "best", sonst tu ich mir das nicht an. Nur so viel: Schreibfehler sind da nicht drin, was du durch Ausprobieren auch rausgefunden hättest.



  • Nun den shift-Operator konnte ich bis jetzt verstehen

    und was heisst nun n>>=1 ?

    ;n ist mir auch net gelaeufig



  • lookias schrieb:

    und was heisst nun n>>=1 ?

    Analog zu (a+=2) == (a=a+2) heißt das n=n>>1.

    ;n ist mir auch net gelaeufig

    Naja, for-Schleifen sehen so aus:

    for (initialisierung; bedingung; durchlaufaktion)
    

    Wenn Du nichts initialisieren möchtest, dann schreibst Du einfach

    for (;bedingung; durchlaufaktion)
    


  • Gut ok danke, hatte das Komma uebersehen.

    ++i,n>>=1
    

    Also das mit dem Komma hab ich auch noch nie gesehen,

    ist das so Konvention fuer for Schleifen oder wo kann man das noch machen?

    Wird n irgendwie false wenn man es lang genug durch 2 teilt, oder ebend die bits verschiebt?



  • Es wird irgendwann 0 und das bedeutet false.



  • lookias schrieb:

    Also das mit dem Komma hab ich auch noch nie gesehen,

    Das ist der Komma-Operator.



  • Danke vielmals ich muss doch immer wieder feststellen, wie wenig ich doch kann 😞

    Ich denke auch, dass MFK's Loesung die Bessere ist, da meine ja schliesslich das Selbe bedeutet, als wenn man die 2 solange potenziert bis man ueber n liegt. 😉



  • lookias schrieb:

    Danke vielmals ich muss doch immer wieder feststellen, wie wenig ich doch kann 😞

    Das würde ich als gutes Zeichen deuten. Solange man das noch merkt, kann man lernen. 🙂

    Ich denke auch, dass MFK's Loesung die Bessere ist, da meine ja schliesslich das Selbe bedeutet, als wenn man die 2 solange potenziert bis man ueber n liegt. 😉

    Sie hat aber gegenüber der Aufgabenstellung noch ein Obiwanproblem, denn bei einer Zweierpotenz als Eingabewert sollte derselbe Wert rausgegeben werden. Meine Funktion gibt die nächste Zweierpotenz aus.


Anmelden zum Antworten