Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Rätselecke » powerOfTwo

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ] [ 3 ]
000
05.07.2004, 11:13 Uhr
(un)wissender
Niveauwart


Zu schreiben ist eine Funktion, die einen unsigned Wert bekommt und diesen abbildet(zurückliefert), und zwar als:
1 -> 0
2 -> 1
4 -> 2
8 -> 3
16 -> 4
32 -> 5.

Wohin würde 23 abgebildet werden?
23 > 16 && 23 < 32 -> 5.
Drei würde nach 2, fünf nach 3 abgebildet werden, usw.

Ich hoffe, dass das Prinzip klar ist.
Gewonnen hat die performanteste Lösung, alle ANSI-Libs sind erlaubt.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
05.07.2004, 11:31 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)



C++:
int ld(int x){return ceil(log(x)/log(2));}

--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
05.07.2004, 11:35 Uhr
(un)wissender
Niveauwart


Perfekt!
Schade, Rätsel ist vorbei.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
05.07.2004, 11:37 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


@(un)wissender
hmm weiss ich gar nicht ob das auf performance bezogen perfekt ist. eventuell ist das besser sich einen ganzahlen log-2 selber zu basteln...
war ich aber zu faul zu.
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
05.07.2004, 12:25 Uhr
ao

(Operator)


Am performantesten sind bei sowas im allgemeinen Tabellen-Lösungen. Ich hab hier einen Vorschlag; wer mag, kann ja mal den Performance-Vergleich mit Windalfs Lösung machen.


C++:
#include <stdio.h>

typedef struct _stLog2LookupEntry
{
    unsigned int m_nNumber;
    unsigned int m_nLog2;
} stLog2LookupEntry;

stLog2LookupEntry g_l2leLookupTable [] =
{
    { 1, 0 }
    , { 2, 1 }
    , { 4, 2 }
    , { 8, 3 }
    , { 16, 4 }
    , { 32, 5 }
    , { 64, 6 }
    , { 128, 7 }
    , { 256, 8 }
    , { 512, 9 }
    , { 1024, 10 }
    , { 2048, 11 }
    , { 4096, 12 }
    , { 8192, 13 }
    , { 16384, 14 }
    , { 32768, 15 }
    , { 65536, 16 }

    , { 0, 32 }
};


unsigned int log2 (unsigned int x)
{
    stLog2LookupEntry * pEntry = g_l2leLookupTable;

    /* Durchsuche die Tabelle von oben nach unten,
       bis du in der linken Spalte
       auf einen Eintrag triffst, der größer oder gleich
       deiner Zahl x ist. Der Eintrag in der rechten Spalte
       ist der gesuchte Zweier-Logarithmus.
       Die zweite Bedingung (m_nNumber > 0) testet auf das
       Tabellen-Ende. */

    while ((pEntry->m_nNumber < x) && (pEntry->m_nNumber > 0))
    {
        pEntry++;
    }

    return pEntry->m_nLog2;
}


int main (void)
{
    unsigned int nNumber = 1;
    unsigned int nLog2;

    while (nNumber > 0)
    {
        scanf ("%d", &nNumber);
        nLog2 = log2 (nNumber);
        printf (" log2(%d) = %d\n", nNumber, nLog2);
    }

    return 0;
}



Das Beispiel geht in C und in C++.

Ich war zu faul, die ganzen Zweierpotenzen bis 2^31 einzutippen, drum hab ich bei 2^16 aufgehört.

Die main-Funktion holt einen Wert von der Tastatur ab, berechnet den Logarithmus und gibt beides aus (ohne irgendwelche Prüfungen, also mit Sorgfalt benutzen!). Bei Eingabe von 0 wird das Programm beendet.

Performance-testen sollte man natürlich nur den Aufruf von log2().

ao

Dieser Post wurde am 05.07.2004 um 12:26 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
05.07.2004, 12:39 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


@ao
deine Lösung ist bei mir ca 3 mal so schnell...
die Scheiss Logarithmen brauchen bei den Taylorreihen halt zu lange zum konvergieren....
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
05.07.2004, 12:46 Uhr
ao

(Operator)


Hinzufügen möchte ich noch, dass solche selbstgestrickten Lösungen wie die von mir fast immer zweite Wahl sind. Ich würde Windalfs High-Level-ANSI-Lösung immer vorziehen, es sei denn, es gibt *tatsächlich* ein Performance-Problem *und* die Verwendung von ceil und log ist *nachweislich* die Ursache.

Wobei ich Windalfs Lösung noch so erweitern würde:

C++:
int ld(int x){return ceil(0.5 + log(x)/log(2));}

um vor Rundungsfehlerchen beim Hin- und Herwandeln zwischen int und double sicher zu sein.

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
05.07.2004, 12:56 Uhr
ao

(Operator)



Zitat:
Windalf postete
ca 3 mal so schnell...

Mehr nicht? OK, das fällt krasser aus auf Maschinen, die keine FPU haben und für Fließkomma-Operationen eine Software-Bibliothek bemühen müssen. Auf modernen PCs und bei normalen Programmen (die nicht hunderttausendmal pro Sekunde einen ganzzahligen Logarithmus brauchen) kann man sich solche Tricksereien also echt sparen.

Die Moral von der Geschicht: Leute, *verwendet* eure Bibliotheken anstatt sie neu zu schreiben.

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
05.07.2004, 12:56 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)



Zitat:

Windalfs High-Level-ANSI-Lösung


Interessant was sich alles so high-level nennen darf
das man logarithmenbasen transformieren kann lernt man ja schon in der Schule. Hab mir in keinster weise was neues ausgedacht sondern nur vermitteltes wissen 1:1 angewendet
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
05.07.2004, 13:13 Uhr
ao

(Operator)



Zitat:
Windalf postete
Interessant was sich alles so high-level nennen darf

Ich meinte high-level in dem Sinne, dass man möglichst mächtige fertige Bausteine aus Bibliotheken verwenden und möglichst wenig Code selber schreiben sollte. Dein Code gibt nur die mathematische Formel wieder: Logarithmus zur Basis 2 berechnen und nach oben aufrunden, und das versteht auch jeder sofort.

Die Rödelarbeit überlässt du den Lib-Funktionen, was den Vorteil hat, dass es auf jedem System sofort laufen wird, egal ob 8-Bit-Mikrocontroller oder 64-Bit-Großrechner.

Mein "hochoptimierter" Code muss bei jeder Portierung geprüft werden: ob der int-Zahlenbereich groß genug ist, ob die Tabelle lang genug ist ...
Und ohne Kommentierung ist es nur für erfahrene Leute lesbar.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ] [ 3 ]     [ Rätselecke ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: