Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preprocessing exponent of const number

Tags:

c

preprocessor

My issue: I want to get an id with N_DIGITS digits and I would like N_DIGITS to be customizable at preprocessing. My id is an integer so I want to define 10^N_DIGITS as the maximum of this number.

In other words: is it possible to preprocess a number with a macro as exponent?

Here is my ultimate attempt:

#include <stdio.h>

#define N_DIGITS 5
#define MAX_N    10e ## N_DIGITS

int main()
{
    printf("%d\n", MAX_N);
    return 0;
}

Of course, this doesn't work and the error is error: exponent has no digits. I don't see why the principle could not be implemented since everything is known by the compiler but I might be wrong.

Anyway my syntax is incorrect, can I get some help here?

like image 678
MatPy Avatar asked Feb 16 '21 10:02

MatPy


2 Answers

Token pasting is done before macro expansion, so you will get 10eN_DIGITS which isn't a valid token.

What you can do is have two levels of a function-like macro - one level to do the macro expansion followed by another one to do the pasting:

#define N_DIGITS 5
#define MAKE_EXPONENT2(exp) 10e ## exp
#define MAKE_EXPONENT(exp) MAKE_EXPONENT2(exp)
#define MAX_N    MAKE_EXPONENT(N_DIGITS)

This makes MAX_N expand to 10e5.

Other issues:

  • 10e5 is a double constant so needs to be printed with %f, not %d.
  • If you want 10 to the power of 5 then you need 1e5 rather than 10e5.
  • Using a floating-point constant to deal with integer data may cause in loss of precision.
like image 173
interjay Avatar answered Oct 28 '22 07:10

interjay


You could do something like this:

#define N_DIGITS 4

#if N_DIGITS == 1
#define MAX_N    1
#elif N_DIGITS == 2
#define MAX_N    10
#elif N_DIGITS == 3
#define MAX_N    100
#elif N_DIGITS == 4
#define MAX_N    1000
#elif N_DIGITS == 5
#define MAX_N    10000
#else
#error N_DIGITS not in [1..5]
#endif

It's not very elegant, but at least you get integer constants and not floating point constants.

like image 26
Jabberwocky Avatar answered Oct 28 '22 08:10

Jabberwocky