Berechnungen beim compilieren

OP #497836
Lesenswert?
• ▲
▼
Ich versuche ein Makro zu schreiben, das eine Variable in Abhängigkeit 
von einer Konstanten mit einer 2er Potenz multiplizieren soll, so dass 
es keinen Überlauf gibt.
Hier ein paar Beispiele die verdeutlichen was ich machen möchte:
y=pmul(x,13);
x soll hier mit 13*16=208 multipliziert werden, denn 16 ist die größte 
2er Potenz, die sicherstellt, dass das Ergebnis nicht größer als 65535 
werden kann (x=8bit, y=16bit).
y=pmul(x,68);
x soll nun mit 2*68=136 multipliziert werden, denn 2 ist die größte 2er 
Potenz, die sicherstellt, dass das Ergebnis nicht größer als 65535 
werden kann.

In einer Funktion wäre das ganze kein Problem, allerdings kann dann der 
konstante Faktor dann nicht mehr zur Laufzeit berechnet werden. Da der 
Faktor aber auch ein Fließkommazahl sein kann, möchte ich das gerne 
vermeiden.

Ich suche also einen Trick, um zur Compilezeit 255/n zu berechnen und 
das Ergebnis auf eine 2er Potenz abzurunden
Gast #497863
Lesenswert?
• ▲
▼
Ich habs ja nicht ganz kapiert, was du willst, aber wenn mir bei so 
etwas gar nichts mehr einfällt, und n zur Compilezeit feststeht, dann 
geife ich gerne mal zu Excel, und bau mir eine Tabelle der Art:
(wer will schon Schönheitspreise für das eleganteste Programm...)

#define pmul_1(x) ((65536/2)*(x))
#define pmul_2(x) ((65536/2)*(x))
#define pmul_3(x) ((65535/4)*(x))
...
#define pmul_255(x) ((((65535/256)*(x))

das in eine Headerdatei kopiert, und dann im Programm als

y = pmul_13(x);

aufgerufen. Vielleicht müssen da noch ein paar typecasts rein, aber 
prinzipiell müsste es doch so gehen, oder?

Oliver
Moderator Persönliche Seite #497889
Lesenswert?
• ▲
▼
Ist das nicht sowas wie ein Logarithmus?

Das hier sollte doch sowas tun:
1
#define MAXPOW2(x) \
2
  (\
3
  (x) >= 128? 1:\
4
    (\
5
    (x) >= 64? 2:\
6
      (\
7
      (x) >= 32? 4:\
8
        (\
9
        (x) >= 16? 8:\
10
          (\
11
          (x) >= 8? 16:\
12
            (\
13
            (x) >= 4? 32:\
14
              (\
15
              (x) >= 2? 64: 128\
16
              )\
17
            )\
18
          )\
19
        )\
20
      )\
21
    )\
22
  )

Die Einrückungen sind nur der Schönheit wegen :), man kann das
natürlich auch etwas kompakter schreiben:
1
#define MAXPOW2(x) ((x)>=128?1:((x)>=64?2:((x)>=32?4:((x)>=16?8:((x)>=8?16:((x)>=4?32:((x)>=2?64:128)))))))

  
OP #497896
Lesenswert?
• ▲
▼
Ganz so einfach ist es leider nicht, da die Konstante eine beliebige 
Kommazahl zwischen 0 und 65536 sein kann. Lookup Tabelle o.ä. fallen 
also weg.
Da es bei diesem Zahlenbereich nur 15 Möglichkeiten gibt, könnte ja 15 
verschiedene Funktionen machen, also

#define pmul_1(x, n) ((x)*((n)*1)
#define pmul_2(x, n) ((x)*((n)*2)
#define pmul_4(x, n) ((x)*((n)*4)
#define pmul_8(x, n) ((x)*((n)*8)
#define pmul_16(x, n) ((x)*((n)*16)
#define pmul_32(x, n) ((x)*((n)*32)
#define pmul_64(x, n) ((x)*((n)*64)
...
#define pmul_32768(x, n) ((x)*((n)*32768)

Was ich suche ist, wie ich #if #elif #endif in einem Makro anwende.

Wenn ich also im Programm pmul(x, 5) schreibe, soll das Programm 
pmul_32(x, 5) ausführen, also x*160 berechnen.

#if (n<2)
 pmul_128(x,n)
#elif (n<4)
 pmul_164(x,n)
#elif (n<8)
 pmul_132(x,n)
#elif (n<16)
 pmul_132(x,n)
...
#else
 pmul_11(x,n)
#endif


Mist, zu lange geschrieben, Jörg war schneller.
Ich denke mal das ist genau das was ich suche. Ich werde es mal 
ausprobieren, schonmal Danke !

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.