Precision upto n decimal points

Discussion in 'C Programming' started by Pp, Dec 4, 2011.

  1. Pp

    Pp Guest

    I am writing power series expansion programs.

    For eg.
    e^x = 1 + x + x^2/2! + x^3/3! + .....

    Depending on how much precision I need, how do I stop the expansion.

    For eg. if I need up to precision 5 then my loop will run in the form


    double ex;
    double newterm;
    // new term is 1 in first iteration
    // is x in 2nd iteration
    // is x^2/2! in 3rd iteration & so on.

    do
    {

    calculate newterm;

    ex = ex + newterm;

    } while (newterm > 1.0e-5);

    Is the right way to do it or is there a better way do this?

    What about for expansions for stuff like cos(x), sin(x) where negative
    terms are involved?
     
    Pp, Dec 4, 2011
    #1
    1. Advertising

  2. On Dec 4, 10:57 am, Pp <> wrote:

    > I am writing power series expansion programs.
    >
    > For eg.
    > e^x = 1 + x + x^2/2! + x^3/3! + .....
    >
    > Depending on how much precision I need, how do I stop the expansion.


    when you've reached the required precision

    > For eg. if I need up to precision 5 then my loop will run in the form
    >
    > double ex;
    > double newterm;
    > // new term is 1 in first iteration
    > // is x in 2nd iteration
    > // is x^2/2! in 3rd iteration & so on.
    >
    > do
    > {
    >         calculate newterm;
    >         ex = ex + newterm;
    > } while (newterm > 1.0e-5);
    >
    > Is the right way to do it or is there a better way do this?


    given that IANA Numerical Analalyst, yes looks fine to me


    > What about for expansions for stuff like cos(x), sin(x) where negative
    > terms are involved?


    > } while (fabs(newterm) > 1.0e-5);


    perhaps?
     
    Nick Keighley, Dec 4, 2011
    #2
    1. Advertising

  3. Pp

    Tim Prince Guest

    On 12/4/2011 5:57 AM, Pp wrote:
    > I am writing power series expansion programs.
    >
    > For eg.
    > e^x = 1 + x + x^2/2! + x^3/3! + .....
    >
    > Depending on how much precision I need, how do I stop the expansion.
    >
    > For eg. if I need up to precision 5 then my loop will run in the form
    >
    >
    > double ex;
    > double newterm;
    > // new term is 1 in first iteration
    > // is x in 2nd iteration
    > // is x^2/2! in 3rd iteration & so on.
    >
    > do
    > {
    >
    > calculate newterm;
    >
    > ex = ex + newterm;
    >
    > } while (newterm > 1.0e-5);
    >
    > Is the right way to do it or is there a better way do this?
    >
    > What about for expansions for stuff like cos(x), sin(x) where negative
    > terms are involved?
    >

    When you have performed range reduction (taking advantage of the
    periodicity), so that your series covers at most 2 quadrants, you can
    figure out ahead of time the number of terms you require, and apply
    Horner evaluation. Methods such as Chebyshev economization will improve
    the convergence rate of the series on the fixed interval.

    --
    Tim Prince
     
    Tim Prince, Dec 4, 2011
    #3
  4. On Sun, 04 Dec 2011 16:27:37 +0530, Pp <> wrote:

    >I am writing power series expansion programs.
    >
    >For eg.
    >e^x = 1 + x + x^2/2! + x^3/3! + .....
    >
    >Depending on how much precision I need, how do I stop the expansion.
    >
    >For eg. if I need up to precision 5 then my loop will run in the form
    >
    >
    >double ex;
    >double newterm;
    >// new term is 1 in first iteration
    >// is x in 2nd iteration
    >// is x^2/2! in 3rd iteration & so on.
    >
    >do
    >{
    >
    > calculate newterm;
    >
    > ex = ex + newterm;
    >
    >} while (newterm > 1.0e-5);


    This only works if the fabs(final value) < 10.

    If x is 15, then the answer to five significant digits is 3.2690e+6
    and, using your philosophy, you should stop when newterm < 1e+5.

    Basically, the limit you test against needs to be scaled by both the
    number of significant digits and the base 10 log of the final value.

    >
    >Is the right way to do it or is there a better way do this?


    In your example, let us assume that newterm falls below the test limit
    in iteration N. You now have a five digit value ABCDE and some
    indication of where to insert the decimal point. It is still possible
    that executing the loop another dozen (or hundred) times will update
    the value to ABCDF. You need to understand how Numerical Analysis is
    capable of determining the maximum error after a particular iteration.

    >What about for expansions for stuff like cos(x), sin(x) where negative
    >terms are involved?


    Still part of Numerical Analysis.

    --
    Remove del for email
     
    Barry Schwarz, Dec 4, 2011
    #4
  5. Pp

    Eric Sosman Guest

    On 12/4/2011 5:57 AM, Pp wrote:
    > I am writing power series expansion programs.
    >
    > For eg.
    > e^x = 1 + x + x^2/2! + x^3/3! + .....
    >
    > Depending on how much precision I need, how do I stop the expansion.
    >
    > For eg. if I need up to precision 5 then my loop will run in the form
    >
    >
    > double ex;
    > double newterm;
    > // new term is 1 in first iteration
    > // is x in 2nd iteration
    > // is x^2/2! in 3rd iteration & so on.
    >
    > do
    > {
    >
    > calculate newterm;
    >
    > ex = ex + newterm;
    >
    > } while (newterm > 1.0e-5);
    >
    > Is the right way to do it or is there a better way do this?


    This will work for the series you mention, and for many others.
    It might fail for some peculiar kinds of series, like x^3*e^x (the
    expansion consists of the series you show, but with three zeroes
    tacked on at the start; your criterion would stop at the first zero
    and never evaluate the remaining terms).

    Also, note that "newterm is small" does not necessarily imply
    that the sum is accurate. For example, consider the harmonic series
    1, 1/2, 1/3, ... Your loop would stop after around ten thousand terms
    and would announce that the series adds to about 9.79. Alas, the
    harmonic series does not converge at all! The terms get smaller, yes,
    but they do not get small "fast enough" for convergence. So, beware!

    > What about for expansions for stuff like cos(x), sin(x) where negative
    > terms are involved?


    The fabs() function is your friend ...

    Many iterative numerical calculations use two (or even more)
    stopping criteria: They'll stop after the calculation converges to
    a suitable accuracy, or they'll stop and announce failure if the
    calculation just buzzes around and around and doesn't converge.

    --
    Eric Sosman
    d
     
    Eric Sosman, Dec 4, 2011
    #5
  6. Pp

    James Kuyper Guest

    On 12/04/2011 05:57 AM, Pp wrote:
    > I am writing power series expansion programs.
    >
    > For eg.
    > e^x = 1 + x + x^2/2! + x^3/3! + .....
    >
    > Depending on how much precision I need, how do I stop the expansion.
    >
    > For eg. if I need up to precision 5 then my loop will run in the form
    >
    >
    > double ex;
    > double newterm;
    > // new term is 1 in first iteration
    > // is x in 2nd iteration
    > // is x^2/2! in 3rd iteration & so on.
    >
    > do
    > {
    >
    > calculate newterm;
    >
    > ex = ex + newterm;
    >
    > } while (newterm > 1.0e-5);
    >
    > Is the right way to do it or is there a better way do this?


    Other people have answered your direct question; I'll deal with a slight
    different issue. You're targeting a fixed precision of 1e-5, which may
    be entirely appropriate approach for a particular problem. However, it's
    not uncommon, for a general purpose function, to want to achieve the
    maximum precision that's possible. There's a very simple way to impose
    that requirement:

    double ex, newterm, last;

    ex = initial_estimate;

    do
    {
    last = ex;
    // calculate newterm
    ex = ex + newterm;
    } while (ex != last);

    > What about for expansions for stuff like cos(x), sin(x) where negative
    > terms are involved?


    With the approach I just outlined, it doesn't matter whether newterm is
    positive or negative.
    --
    James Kuyper
     
    James Kuyper, Dec 4, 2011
    #6
  7. Pp

    Weland Guest

    On 2011-12-04, Pp <> wrote:
    > I am writing power series expansion programs.
    >
    > For eg.
    > e^x = 1 + x + x^2/2! + x^3/3! + .....
    >
    > Depending on how much precision I need, how do I stop the expansion.
    > [...]
    > What about for expansions for stuff like cos(x), sin(x) where negative
    > terms are involved?
    >


    Store two consecutive approximations and compute their difference? At least
    that's how I saw it done most of the time.

    So if e^x = s(1) + s(2) + ... + s(n) + ...

    then two consecutive approximations would be

    e^x_(k) = s(1) + s(2) + ... + s(k)
    e^x_(k+1) = s(1) + s(2) + ... + s(k) + s(k+1)

    and the stopping criteria would be

    abs(e^x_(k)) - abs(e^x(k+1)) < some threshold

    Feel free to jug the abs()s around depending on how you expect the series
    expansion to go (e.g. depending on it being monotonically increasing or not,
    or if you're expanding around a function's 0 point and you're concerned
    about it swinging above and below 0).

    Depending on what you're trying to achieve you might also be better
    off checking against a relative error, not an absolute one.

    --

    SDF Public Access UNIX System - http://sdf.org
    % grep me no patterns and I'll tell you no lines
     
    Weland, Dec 4, 2011
    #7
  8. Pp

    Lauri Alanko Guest

    In article <jbg2on$b8b$>,
    James Kuyper <> wrote:
    > do
    > {
    > last = ex;
    > // calculate newterm
    > ex = ex + newterm;
    > } while (ex != last);


    That seems dangerous. Depending on the calculation, ex might
    eventually oscillate between two numbers. Comparing floats for
    equality is in general a bad idea, unless you know really well what
    you are doing.


    Lauri
     
    Lauri Alanko, Dec 4, 2011
    #8
  9. Pp

    James Kuyper Guest

    On 12/04/2011 10:29 AM, Lauri Alanko wrote:
    > In article <jbg2on$b8b$>,
    > James Kuyper <> wrote:
    >> do
    >> {
    >> last = ex;
    >> // calculate newterm
    >> ex = ex + newterm;
    >> } while (ex != last);

    >
    > That seems dangerous. Depending on the calculation, ex might
    > eventually oscillate between two numbers. Comparing floats for
    > equality is in general a bad idea, unless you know really well what
    > you are doing.


    Yes, that approach requires that the sum of the series converges; a
    novice shouldn't even attempt doing a partial sum of a non-convergent
    series, and an expert needs to be very careful about determining the
    best number of terms to use.
    Also, a series that converges mathematically might not do so when using
    floating point math on a computer - again, that's an issue for experts
    to deal with, there's no easy solution for the novice to learn.
    --
    James Kuyper
     
    James Kuyper, Dec 4, 2011
    #9
  10. Pp

    gwowen Guest

    On Dec 4, 10:57 am, Pp <> wrote:

    > do
    > {
    >         calculate newterm;
    >         ex = ex + newterm;
    > } while (newterm > 1.0e-5);


    what if the nth term is 1.0e-6 for all n?

    > Is the right way to do it


    No. The nth term being small does not guarantee that the sum of the
    nth->infinity will be similarly small.

    > or is there a better way do this?


    No. There is no general way to determine if a given series will
    converge, let alone whether it *has* converged. For specific examples,
    you may be able to bound the sum of the tail of the series and use
    that bound.
     
    gwowen, Dec 5, 2011
    #10
  11. Pp

    gwowen Guest

    On Dec 4, 3:46 pm, James Kuyper <> wrote:

    > Also, a series that converges mathematically might not do so when using
    > floating point math on a computer


    .... and vice versa!
     
    gwowen, Dec 5, 2011
    #11
    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. Piotr

    Decimal precision ?

    Piotr, Apr 2, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    1,581
    Martin Dechev
    Apr 2, 2004
  2. =?ISO-8859-1?Q?Mattias_Br=E4ndstr=F6m?=

    Arbitrary precision decimal numbers

    =?ISO-8859-1?Q?Mattias_Br=E4ndstr=F6m?=, Apr 21, 2005, in forum: C++
    Replies:
    5
    Views:
    524
    Alex Vinokur
    Apr 26, 2005
  3. Sam
    Replies:
    2
    Views:
    2,152
  4. Replies:
    3
    Views:
    297
  5. Kay Y. Jheallee

    Setting longer default decimal precision

    Kay Y. Jheallee, Nov 18, 2013, in forum: Python
    Replies:
    7
    Views:
    108
    Tim Golden
    Nov 20, 2013
Loading...

Share This Page