under/over flow problem?

Discussion in 'C Programming' started by questions?, Apr 7, 2006.

  1. questions?

    questions? Guest

    I have a problem involves under flow/over flow.

    ###################################################
    # include <stdio.h>
    # include <math.h>
    # include <stdlib.h>

    double rate;
    double t;
    double u;

    int main(){
    int i;
    double diff;
    double rtime;;
    t=0.0047590000;
    diff=t/10;
    rtime=0;
    rate=0.00000000000001;

    for(i=0;i<10;i++){
    printf("real time is:%.50lf and current time:%.50lf\n",t,rtime);
    u=(1-exp(-1*rate*rtime))/(1-exp(-1*rate*t));
    printf("for the %d th time, u=%.50lf\n",i,u);
    rtime=rtime+diff;
    }
    return 0;
    }


    ************************

    The idea is that,u is a monotonically increaseing function of rtime,
    as rtime increase from 0 to t, u increase from 0 to 1.

    But appearantly it runs into underflow/overflow.

    how can I deal with this problem nicely? Roughly, how precise is C
    double?

    Thanks for comments
    questions?, Apr 7, 2006
    #1
    1. Advertising

  2. questions?

    Me Guest

    questions? wrote:
    > I have a problem involves under flow/over flow.
    >
    > ###################################################
    > # include <stdio.h>
    > # include <math.h>
    > # include <stdlib.h>
    >
    > double rate;
    > double t;
    > double u;
    >
    > int main(){
    > int i;
    > double diff;
    > double rtime;;
    > t=0.0047590000;
    > diff=t/10;
    > rtime=0;
    > rate=0.00000000000001;
    >
    > for(i=0;i<10;i++){
    > printf("real time is:%.50lf and current time:%.50lf\n",t,rtime);
    > u=(1-exp(-1*rate*rtime))/(1-exp(-1*rate*t));
    > printf("for the %d th time, u=%.50lf\n",i,u);
    > rtime=rtime+diff;
    > }
    > return 0;
    > }
    >
    >
    > ************************
    >
    > The idea is that,u is a monotonically increaseing function of rtime,
    > as rtime increase from 0 to t, u increase from 0 to 1.
    >
    > But appearantly it runs into underflow/overflow.
    >
    > how can I deal with this problem nicely?


    Use <= instead of <.

    > Roughly, how precise is C double?


    Check the standard for the minimum limits, check <limits.h> for your
    implementation's limits.
    Me, Apr 7, 2006
    #2
    1. Advertising

  3. questions?

    Eric Sosman Guest

    questions? wrote:

    > I have a problem involves under flow/over flow.
    > [code snipped; see up-thread]


    Overflow and underflow don't appear to be involved;
    your problem appears to arise from finite precision.

    Specifically, let's look at the denominator in the
    expression for `u':

    u = (stuff) / (1 - exp(-1 * rate * t));

    Elsewhere in the code, we find that `rate' is 1e-14 and `t' is
    4.759e-3, so the argument to exp() is approximately -4.759e-17.
    This value is very close to zero, so its exponential will be
    very close to one, and the denominator of the fraction will be
    very close to zero.

    ... and that's where precision enters the picture. The
    computer has a finite amount of memory, and cannot represent the
    value exp(-4.759e-17) with perfect accuracy. (Most computers are
    unable even to store the rational number -4.759e-17 with perfect
    accuracy, but that's just a distraction at this point.) Instead,
    the computer does what humans do: It uses finite approximations
    when it calculates, rounding the values to a machine-specific
    number of places.

    How many places? C requires `double' to provide at least
    ten decimal digits' worth of precision; most machines nowadays do
    better by providing about fifteen digits. But when rounded to
    fifteen places, exp(-4.759e-17) is equal to unity; the departure
    from unity is too small to represent. That makes the denominator
    equal to `1 - 1', which in turn makes the calculation of `u'
    meaningless.

    > how can I deal with this problem nicely? Roughly, how precise is C
    > double?


    The actual precision of your machine's `double' is described
    by the macros defined in <float.h> (not in <limits.h>, as another
    poster mistakenly wrote).

    There are at least two possibilities for a cure. First, you
    could try switching to `long double', which on some machines has
    more precision than `double' and might have enough precision to
    make something sensible of the calculation. However, `long double'
    is only supported meaningfully on a few machines; on many, it is
    really just `double' all over again. Consult <float.h> to see
    whether `long double' gains any precision on your system.

    The second and more promising possibility is to do some math,
    and reorganize the calculation so it doesn't require such great
    precision. Maybe you can find a power series representation that
    doesn't involve subtracting numbers that are very nearly equal, an
    almost foolproof (if that's the right word) way to lose precision.

    Oh, and by the way: There's no such thing as an "%lf"
    conversion specifier for printf(). Use "%f" and its variants --
    and don't even begin to hope for fifty decimal places!

    --
    Eric Sosman
    Eric Sosman, Apr 7, 2006
    #3
  4. questions?

    questions? Guest

    Eric Sosman wrote:
    > questions? wrote:
    >
    > > I have a problem involves under flow/over flow.
    > > [code snipped; see up-thread]

    >
    > Overflow and underflow don't appear to be involved;
    > your problem appears to arise from finite precision.
    >
    > Specifically, let's look at the denominator in the
    > expression for `u':
    >
    > u = (stuff) / (1 - exp(-1 * rate * t));
    >
    > Elsewhere in the code, we find that `rate' is 1e-14 and `t' is
    > 4.759e-3, so the argument to exp() is approximately -4.759e-17.
    > This value is very close to zero, so its exponential will be
    > very close to one, and the denominator of the fraction will be
    > very close to zero.
    >
    > ... and that's where precision enters the picture. The
    > computer has a finite amount of memory, and cannot represent the
    > value exp(-4.759e-17) with perfect accuracy. (Most computers are
    > unable even to store the rational number -4.759e-17 with perfect
    > accuracy, but that's just a distraction at this point.) Instead,
    > the computer does what humans do: It uses finite approximations
    > when it calculates, rounding the values to a machine-specific
    > number of places.
    >
    > How many places? C requires `double' to provide at least
    > ten decimal digits' worth of precision; most machines nowadays do
    > better by providing about fifteen digits. But when rounded to
    > fifteen places, exp(-4.759e-17) is equal to unity; the departure
    > from unity is too small to represent. That makes the denominator
    > equal to `1 - 1', which in turn makes the calculation of `u'
    > meaningless.
    >
    > > how can I deal with this problem nicely? Roughly, how precise is C
    > > double?

    >
    > The actual precision of your machine's `double' is described
    > by the macros defined in <float.h> (not in <limits.h>, as another
    > poster mistakenly wrote).
    >
    > There are at least two possibilities for a cure. First, you
    > could try switching to `long double', which on some machines has
    > more precision than `double' and might have enough precision to
    > make something sensible of the calculation. However, `long double'
    > is only supported meaningfully on a few machines; on many, it is
    > really just `double' all over again. Consult <float.h> to see
    > whether `long double' gains any precision on your system.
    >
    > The second and more promising possibility is to do some math,
    > and reorganize the calculation so it doesn't require such great
    > precision. Maybe you can find a power series representation that
    > doesn't involve subtracting numbers that are very nearly equal, an
    > almost foolproof (if that's the right word) way to lose precision.
    >
    > Oh, and by the way: There's no such thing as an "%lf"
    > conversion specifier for printf(). Use "%f" and its variants --
    > and don't even begin to hope for fifty decimal places!
    >
    > --
    > Eric Sosman
    >



    Thanks for the nice explanation. I at the end, do use an approximation.

    Are there systems/implementation that try to create a high precision
    enviroment?
    questions?, Apr 13, 2006
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fiaz Ali Saleemi

    Stack Over Flow Message in IE

    Fiaz Ali Saleemi, Jul 14, 2005, in forum: ASP .Net
    Replies:
    4
    Views:
    487
    Nic Roche
    Jul 15, 2005
  2. Mark L Pappin

    floating point over-/under-flow

    Mark L Pappin, Dec 2, 2004, in forum: C Programming
    Replies:
    3
    Views:
    585
    Gordon Burditt
    Dec 2, 2004
  3. dragoncoder
    Replies:
    33
    Views:
    1,015
    Pete Becker
    May 23, 2006
  4. Replies:
    7
    Views:
    479
    =?iso-8859-1?Q?M=E5ns_Rullg=E5rd?=
    Jun 12, 2006
  5. Jack Dowson
    Replies:
    0
    Views:
    453
    Jack Dowson
    May 7, 2007
Loading...

Share This Page