conversion problem int <-> double ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Markus Dehmann

    conversion problem int <-> double ?

    I have two integers i1 and i2, the second of which is guaranteed to be
    between 0 and 99, and I encode them into one double:

    double encoded = (double)i1 + (double)i2 / (double)100;

    So, for example, 324 and 2 become 324.02. Now I want to decode them
    using the function given below but it decodes the example as 324 and
    1, instead of 324 and 2.

    Can anyone tell me what's wrong and how to do this right? (my code see
    below)

    Thanks!
    Markus

    #include <iostream>

    void decode(double n, int& i1, int& i2){
    i1 = int(n);
    double rest = n - int(n);
    i2 = int(rest * 100.0); // i2 is 1, should be
    2
    }

    int main(int argc, char** argv){
    double n = 324.02;
    int p;
    int i;
    decode(n, p, i);
    std::cerr << "n=" << n <<", p=" << p << ", i=" << i << std::endl;
    return EXIT_SUCCESS;
    }


  • Greg Herlihy

    #2
    Re: conversion problem int &lt;-&gt; double ?

    On Mar 31, 7:04 pm, Markus Dehmann <markus.dehm... @gmail.comwrote :
    I have two integers i1 and i2, the second of which is guaranteed to be
    between 0 and 99, and I encode them into one double:
    >
    double encoded = (double)i1 + (double)i2 / (double)100;
    >
    So, for example, 324 and 2 become 324.02. Now I want to decode them
    using the function given below but it decodes the example as 324 and
    1, instead of 324 and 2.
    The problem is that floating point values usually have a binary
    representation. So precise decimal values (such as 324.02) often
    cannot be exactly represented with a floating point type. Instead, the
    floating point type stores the representable value nearest to the
    value specified (for example, the nearest representable value to
    324.02 is likely 324.01999).

    One solution would be to use decimal floating point arithmetic.
    Decimal floating point arithmetic would be able to represent 324.02
    exactly. But although support for decimal floating arithmetic is
    likely coming to the C++ library, actual implementations of this
    feature are not that common.

    A more likely (and practical) solution might be to use "fixed-point"
    arithmetic. Fixed point arithmetic is completely accurate - up to the
    specified resolution. For example, performing the above calculation
    with fixed point arithmetic (with 1/100 resolution) might look
    something like this:

    typedef long Fixed; // in 1/100ths of a unit

    Fixed n = 32402;
    long p = n/100;
    long i = n%100;

    Greg

    Comment

    • James Kanze

      #3
      Re: conversion problem int &lt;-&gt; double ?

      On Apr 2, 6:47 am, Jack Klein <jackkl...@spam cop.netwrote:
      On Tue, 1 Apr 2008 01:10:24 -0700 (PDT), James Kanze
      <james.ka...@gm ail.comwrote in comp.lang.c++:
      On Apr 1, 4:44 am, Jack Klein <jackkl...@spam cop.netwrote:
      On Mon, 31 Mar 2008 19:04:01 -0700 (PDT), Markus Dehmann
      <markus.dehm... @gmail.comwrote in comp.lang.c++:
      double encoded = (double)i1 + (double)i2 / (double)100;
      The obvious question is: why? If you really do receive a value
      in this format (i.e. integer part and hundredths as two separate
      values), and want to treat it as a single value, fine, but then
      I don't understand why you want to go the other direction later.
      And I can't think of any other reason why one would want to do
      this.
      I rather think I covered this in my next sentence:
      Which is:
      This is not a very good idea, as you have found. The
      floating point data types in C, and just about every other
      computer language, use a fixed number of bits, and that
      limits their precision.
      I can see reasons why one might want to do this on input. Some
      external source is providing an integral value, followed by an
      integral number of 100ths, and you want to do various
      calculations on those values. Since the input is with an
      accuracy of at most a 100th, you'll normally only output with
      this accuracy as well, and for most trivial compuations, you can
      pretty much ignore the rounding errors (which will be far
      smaller).

      I can't see a reason why one would want to go back, however.
      (Maybe outputting to the same device?)

      [...]
      Can anyone tell me what's wrong and how to do this
      right? (my code see below)
      Your basic idea is wrong.
      Hard to say without really knowing what his basic idea
      is:-). Why does he want to do this? Anyway, two "obvious"
      solutions come to mind:
      Without knowing his reasoning, I gave him the benefit of the doubt,
      and still decided that he was wrong. If he worked for my company, he
      wouldn't write code that way a second time after the first code
      review.
      Even if it was what the requirements spefication demanded?
      There are no "non-icky" ways to do this. If its a space issue
      of some type, I will bet there are very few platforms where
      sizeof(std::div _t) is greater than sizeof(double).
      I can't really believe that it's a space issue, since a double
      generally is the size of two int, and his input is two ints.
      Putting the two values into a std::div_t would retain all the
      integer bits with no loss, and still allow easy conversion to
      a double if actually needed for some arcane purpose.
      I wouldn't call computing a new value an "arcane purpose". And
      if some external device is providing input in this format, then
      you have to deal with it. The question is why the round trip.
      Why does he want to go back to the original format?

      --
      James Kanze (GABI Software) email:james.kan ze@gmail.com
      Conseils en informatique orientée objet/
      Beratung in objektorientier ter Datenverarbeitu ng
      9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

      Comment

      Working...