Preprocessor log()?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Richard Cavell

    #1

    Preprocessor log()?

    Hi,

    I want to do something like this:

    const int a = "283529";
    const int b = log to base 2 of a;

    and have it *at compile time*.
  • Chris Torek

    #2
    Re: Preprocessor log()?

    In article <cvrcg3$o4b$1@n nrp.waia.asn.au >
    Richard Cavell <richardcavell@ mail.com> wrote:[color=blue]
    >I want to do something like this:
    >
    >const int a = "283529";
    >const int b = log to base 2 of a;
    >
    >and have it *at compile time*.[/color]

    You cannot even do this:

    % cat foo.c
    const int a = "283529";
    % cc -ansi -pedantic -c foo.c
    foo.c:1: warning: initialization makes integer from pointer without a cast
    %

    Presumably you did not really mean to include the quotes.

    If we fix that, so that "a" is a read-only variable initialized to
    283529, we still have several problems, the first being that "a"
    is a variable. You cannot initialize a second static-storage-duration
    variable based on another variable; you can only use constants to
    initialize static-duration variables. Remember that, in C, const
    means "do not define a constant". (There are other languages in
    which const *does* mean "constant"; but if you mean to use one of
    those languages, you are in the wrong newsgroup.)

    We can repair this by initializing both variables (whether read-only
    or not) from a true constant, using either "#define" or "enum". Note,
    however, that 283529 is a large enough value that it might exceed
    the range for "int", so we really should use "long", and a #define
    -- enumeration constants have type int, and if INT_MAX is 32767, the
    sequence:

    enum { A = 283529 };

    should draw a diagnostic. (If INT_MAX is 2147483647, as it is on so
    many implementations today, no diagnostic is required.) So now we
    have:

    #define A 283529
    const long a = A; /* or int, if you are sure INT_MAX >= 283529 */
    const int b = SOME_MACRO(A);

    and we need to find a way to define SOME_MACRO so as to obtain
    log2(283529).

    Now we have one final problem: log2(283529) is approximately
    18.113136779327 283. What integer value do you want to represent
    this? Both 18 and 19 are "reasonable " but at most one of them
    is correct (although perhaps neither is correct).

    Depending on your answer to this last problem, there is an obvious
    way to define SOME_MACRO:

    #define SOME_MACRO(x) \
    ((x) > 65536 ? [one set of options] : [other set of options])

    where the expansion of one of the sets-of-options is:

    (x) > 256 ? [one set of options] : [another set of options]

    and these options again expand to something like:

    (x) > 16 ? [one set of options] : [another set of options]

    and so on, ending with:

    (x) > 1 ? 1 : 0

    (with an optional test for x < 1 as well, although what value to
    use here is again a puzzle).

    (This version, with the tests for ">", is designed for rounding
    up, so that b will be set to 19, based on A > 262144; if A is
    between 131073 and 262144 inclusive, the result would be 18.)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.

    Comment

    Working...