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
    std::numeric_limits<T>::max_exponent10
    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.

    Phil
    [* I know bugger all about C++, or at least that's what I claim in public.]
     
    Phil Carmody, Oct 22, 2013
    #21
    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
    #22
    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
    #23
  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
    #24
  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
    #25
  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!
    #endif

    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
    #26
    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.