likern
likern

Reputation: 3964

C macro defines variable length value

I has implemented own tmpnam() function for creating temporary files. I use following defines for adjust this one:

/* The length of random string. In /tmp/test143276 is 143246 */
#define RND_ROUND 6
/* Used as a minimal bound produced by number generator      */
#define RND_MIN 100000
/* Used as a maximum bound produced by number generator      */
#define RND_MAX 1000000

As you can see the real needed macro is RND_ROUND and others are derivative to pass to the number generator. And the formula for generating is:

RND_MIN = 1 and [RND_ROUND-1] zeros
RND_MAX = 1 and [RND_ROUND] zeros

Question: How can I create some macro which will produce RND_MIN and RND_MAX based on RND_ROUND at compile time?

Example:

#define RND_ROUND 6
// somehow define those RND_MIN and RND_MAX
...
int32_t random = g_rand_int_range(generator, RND_MIN(RND_ROUND), RND_MAX(RND_ROUND));

Upvotes: 0

Views: 179

Answers (3)

LS_ᴅᴇᴠ
LS_ᴅᴇᴠ

Reputation: 11161

I would suggest you to forget about RND_ROUND: this is compile time, anyway!

#define RND_BASE 1000000
#define RND_MIN RND_BASE
#define RND_MAX (RND_BASE*10)

Now, if you really need RND_ROUND, RND_MIN and RND_MAX at compile time and not being expanded to pow, assuming your RND_ROUND is not you may branch it with #if (note that g_rand_int_range is limited to gint32, so RND_MAX<2^31=2'147'483'648<10^10 is possible):

#if RND_ROUND <= 1
#    define RND_MIN 1
#elif RND_ROUND <= 2
#    define RND_MIN 10
#elif RND_ROUND <= 3
#    define RND_MIN 100
#elif RND_ROUND <= 4
#    define RND_MIN 1000
#elif RND_ROUND <= 5
#    define RND_MIN 10000
#elif RND_ROUND <= 6
#    define RND_MIN 100000
#elif RND_ROUND <= 7
#    define RND_MIN 1000000
#elif RND_ROUND <= 8
#    define RND_MIN 10000000
#else
#    define RND_MIN 100000000
#endif

#define RND_MAX (RND_MIN*10)

This will also be safer, limiting RND_ROUND so that there will not be integer overflows.

Upvotes: 1

Grijesh Chauhan
Grijesh Chauhan

Reputation: 58271

If I am correct you can use power function:

#define RND_MIN(RND_ROUND)  pow(10, RND_ROUND - 1)
#define RND_MAX(RND_ROUND)  pow(10, RND_ROUND)

You may like to read: How to simplify this power equation?

Upvotes: 3

phoxis
phoxis

Reputation: 61920

You can use the power function to do the work.

#define RND_MIN (pow (10, RND_ROUND-1))
#define RND_MAX (pow (10, RND_ROUND))

Or depending on the passed argument.

#define RND_MIN(val) (pow (10, (val)-1))
#define RND_MAX(val) (pow (10, (val)))

Upvotes: 3

Related Questions