Pseudo code to C help needed

Discussion in 'C Programming' started by Mark Storkamp, Oct 22, 2013.

  1. Mark Storkamp

    Phil Carmody Guest

    which I shall call reference 1.

    Strangely, your logic doesn't hold, yet you've got to the right answer!

    Reference 1 is *surely* in error. I believe[*] that the quote
    describes something closer (but an out-by-one out) to
    where the "10" part is key. Were reference 1 to be absolutely
    correct, then the answer would be (modulo out-by-ones):
    imax = 2 * {FLT,DBL,LDBL}_MAX_10_EXP depending on what "Real" is.

    Fortunately, you blasted past that presumed copy-pasto, and reached
    what is almost certainly the right answer.

    However, given that C++ is C++[*], it's possible that imax is used
    in ways that aren't C-compatible (being as it is a const variable,
    rather than a constant), and something bizarre like:
    enum { imax = 2*DBL_MAX_EXP };
    might be necessary to achieve all the constanty goodness that C++
    may[*] provide.

    [* I know bugger all about C++, or at least that's what I claim in public.]
    Phil Carmody, Oct 22, 2013
    1. Advertisements

  2. (snip, I wrote)
    The OP wants to use it as part of a convergence test for an
    iterative approximation to guard against infinite loops.

    Normally there will be a test that exits the loop early, but even
    if there isn't, a few extra iterations isn't so bad.

    The number of iterations often depends on how far you are from
    the right answer, which can scale with exponent size.

    Note that FLT_MAX_EXP does not properly scale if the base
    can be different, but FLT_MAX_10_EXP does.

    -- glen
    glen herrmannsfeldt, Oct 23, 2013
    1. Advertisements

  3. That's correct.
    Two tests, actually. But there are typically as many as 900,000 points
    being tested, so a few extra iterations may add up over time.
    And here you lost me, but I now plan on running two versions, one with
    each constant, and seeing how much, if any, difference there is in the
    results. My raw data is coming from a 3D scanner via an .stl file, so as
    long as my results are accurate to within .001" I'll be okay. Anything
    else is just noise anyway.
    Mark Storkamp, Oct 23, 2013
  4. The raw data is coming from a 3D scan via an .stl file, so the data is
    coming in as floats, all values are less than 20", and resolution less
    than .001" is just noise. When I first started writing this program I
    didn't see any point in converting it to double. Now that the project
    has grown way beyond what I had imagined it to ever be, and I'm doing a
    whole lot more manipulation on the data, it's probably too late to
    change things now, even if it were slightly more efficient.
    Mark Storkamp, Oct 23, 2013
  5. Mark Storkamp

    James Kuyper Guest

    The value of max_exponent is entirely irrelevant to that usage. If
    that's what was being done, the limit should have been expressed in
    terms of std::numeric_limits<Real>::epsilon. With Real a typedef for
    float, that corresponds to FLT_EPSILON.

    It's not exactly impossible that max_exponent is being misused in this
    way - but without seeing the details of the actual code, we can't be
    sure that it is. It's impolite to the writer of the pseudo-code to just
    assume that he is misusing it without know precisely how he used it.

    There's a simple check that the OP could perform: properly written C++
    code that makes use of std::numeric_limits<Real>::max_epsilon should, in
    general, use std::numeric_limits<Real>::radix in close association with
    max_epsilon. Improperly written code will assume that radix==2, and will
    get away with that assumption most of the time. In that case,
    translating it as 7*FLT_MAX_10_EXP, as you suggest, would be safer on
    machines where FLT_RADIX!=2. However, the right fix is to replace 2 with
    FLT_RADIX, or 0.5 with 1/FLT_RADIX, wherever appropriate.
    James Kuyper, Oct 23, 2013
  6. It would have been convenient if they also supplied FLT_MAX_2_EXP.
    My guess is that this is a last resort test, but that could be wrong.

    The problem is that FLT_MAX_EXP depends on FLT_RADIX. Unless you
    are taking the bits apart, any tests that use FLT_MAX_EXP should
    also use FLT_RADIX, but that isn't so convenient in this case.

    I believe they are preprocessor symbols, so you could:

    #if FLT_RADIX!=2
    #error This is meant for a radix 2 system!

    and go on with it.

    Otherwise you need a factor of log(FLT_RADIX)/log(2) in there.

    I have no idea how popular FLT_RADIX==10 machines will get over
    the years, now that they are part of the IEEE standard.

    -- glen
    glen herrmannsfeldt, Oct 23, 2013
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.