Präprozessor - Exponnent

#3275470
Lesenswert?

Hallo zusammen,
kennt jemand eine Möglichkeit, den Präprozessor konstante Potenzen 
berechnen zu lassen? Konkret suche ich etwas wie:
1
#define N_DIGITS 3
2

3
void fcn(uint16_t a) {
4
  a %= pow(10,NDIGITS);
5
  ...
6
}
um den konstanten Term auf der rechten Seite schon im Präprozessor 
ausrechnen zu können. Wenn ich das richtig sehe, gibt es ja keinen 
Exponnentialoperator und keine Schleifen.

Viele Grüße
Nicolas
Gast #3275492
Lesenswert?

Ansonsten wird of so ein workaround gemacht:

#define N_DIGITS 3
#define pow_1(x) (x)
#define pow_2(x) pow_1(x*x)
#define pow_3(x) pow_1(x*x*x)
#define pow_4(x) pow_1(x*x*x*x)
#define pow_5(x) pow_1(x*x*x*x*x)
#define pow_6(x) pow_1(x*x*x*x*x*x)
#define pow_7(x) pow_1(x*x*x*x*x*x)
#define pow_8(x) pow_1(x*x*x*x*x*x)

#define pp_pow__(x,y) pow_##y(x)
#define pp_pow_(x,y) pp_pow__((x),y))
#define pp_pow(x,y) pp_pow_((x),y))

void fcn(uint16_t a) {
  a %= pp_pow(10,N_DIGITS);
  }
Gast #3275500
Lesenswert?

1
#include <iostream>
2
 
3
template <typename T>
4
constexpr const T clPow (const T& base, const unsigned int exp) {
5
    return exp == 0 ? T{1} : clPow<T> (base, exp-1) * base;
6
}
7
 
8
int main () {
9
    constexpr int x = clPow (10, 4);
10
    std::cout << x << std::endl;
11
}
"constexpr" zwingt den Compiler die Werte beim Compilieren auszurechnen. 
Funktioniert außerdem auch zur Laufzeit. So vermeidet man den 
Präprozessor komplett mit allen seinen Fallen & Nachteilen...
#3275627
Lesenswert?

test.c:
1
#include <math.h>
2

3
double test(void)
4
{
5
  return pow(10, 3);
6
}
7

8
int testi(void)
9
{
10
  return pow(10, 3);
11
}

Compile:
1
avr-gcc -c -Os test.c

Ergebnis:
1
test.o:     file format elf32-avr
2

3

4
Disassembly of section .text:
5

6
00000000 <test>:
7
   0:  60 e0         ldi  r22, 0x00  ; 0
8
   2:  70 e0         ldi  r23, 0x00  ; 0
9
   4:  8a e7         ldi  r24, 0x7A  ; 122
10
   6:  94 e4         ldi  r25, 0x44  ; 68
11
   8:  08 95         ret
12

13
0000000a <testi>:
14
   a:  88 ee         ldi  r24, 0xE8  ; 232
15
   c:  93 e0         ldi  r25, 0x03  ; 3
16
   e:  08 95         ret

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren