Thread: Splitting result into different varibles for Maclaurin expansion

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    9

    Splitting result into different varibles for Maclaurin expansion

    I have another problem which I cant seem to figure out,

    I was wondering how it would be possible to calculate a Euler's number using maclaurin's series up to 30~35 digits, until the 30th power.

    f(x)=f(0)+f'(0)+f''(0)*x^2/2!+f'''(0)*x^3/3!+f''''(0)*x^4/4!+...+f^n(0)*x^n/n!

    Is the basic formula, but as the integers in c++ have a certain digit limit It cannot show until up to 30~35 digits.
    That is kinda hard to understand but as i cannot post urls now youd have to google a better one



    I was thinking to split up the value storing the digits by 5 each using series [x] but I cannot figure out how the hell to split up something inside there. As for the calculation of the formula, its not hard as a outer function lets me calculate the factorials.

    as an example,
    for the power being 1,
    i would need a variable x to store the number of that certain power in the expansion. Since the power is 1,
    x=f'(0)=1.0000000000~
    and a variable e which stores the total number calculated thus far.

    As a general form it should go like this.
    pow=1, x=1.000000000~ e=2.0000000000~
    pow=2, x=0.500000000~ e=2.5000000000~
    pow=3, x=1.666666666~ e=2.6666666666~

    So yeah, I know how to use the split storage in order to make the operation between 2 16 digit numbers split into 8 each but in that case, you input the values by yourself, while in this the program should run by itself storing the result of the division.

    Any help would be appreciated.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I'm not sure I know what the difference is you're thinking of. If you know how to split up a 32-bit integer into two 16-bit integer, it doesn't matter where the number comes from? You will have to write routines to operate on these pairs-of-numbers (i.e. you'll have to do carry and things yourself).

  3. #3
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    It sounds like you're looking for a big number library. There are several available, no need to brew your own.

    But I'm not sure that's the best solution. Why are you using integers and not doubles? There are some gotcha's with using floating point numbers, but I suspect for your application they will be sufficient. What are typical high values for x and n that you expect your program to work with?
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  4. #4
    Registered User
    Join Date
    May 2011
    Posts
    9
    Thanks for the answer,

    Basically I need to split the already calculated result into different variables.

    The fact that I used INT is because of the following.

    Lets say that I have declared int x[6]
    And that the result for euler's number expansion of the third exponent is 0.166666666666666666666666666666

    And I want to split it so

    x[0]=0
    x[1]=16666
    x[2]=66666
    and so on
    So I dont really need the use of double because I wont be having anything requiring doubles
    Then I want to add this number to the total of the expanded Euler's number until now.

    The results for the first and second exponential were :
    1.000000000000000000000
    0.500000000000000000000
    those will be added to the total of Euler's number which is I have declared as int e[6].

    In the case of expanding until the third power we get
    e=2.6666666666666666666666
    Which is basically by adding all what we get from the formula.
    This too will be split into numbered variables like x was
    What I am thinking is that there could be added some variation to the division in the formula to gain the exact number I need for each part, but i still don't get it

    Adding up the sum is something i have done and Is possible, but what I really want is how to get the specific value stored in the specific variable slot

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So you don't want bignum, or even splitting(!), but rather just fixed point. I forget right now whether GMP has such (or equivalent high-precision float). Note also that division isn't going to get you from 0.16666 to 16666....

  6. #6
    Registered User
    Join Date
    May 2011
    Posts
    9
    This was supposed to be achievable by only having knowledge about series, but I dont understand how the hell to split these

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So I guess the question is: why are you using int? Why aren't you using long double? Are you actually supposed to have 30 decimal digits of accuracy, or will you settle for 18 (which is what long double guarantees on my machine)?

  8. #8
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Edit: I am trying to understand this problem likely will be doing Taylor Series (super set of Maclaurin expansion) this fall.

    Links that help me understand what is being asked; still have no understanding of how to do it.

    Euler's number
    e (mathematical constant) - Wikipedia, the free encyclopedia

    Note: To increase accuracy you can add the smaller terms first when calculating "Euler's number (e)"; but, I have no idea if this applies directly with Maclaurin expansion method.

    http://en.wikipedia.org/wiki/Taylor_series
    http://en.wikipedia.org/wiki/Exponential_function


    Big Integer Library; still have only a slight understanding why OP wants to do it using Integers; never heard/used of this library before.
    https://mattmccutchen.net/bigint/


    Tim S.
    Last edited by stahta01; 07-13-2011 at 10:52 AM. Reason: Re-wrote it from scratch

  9. #9
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    For ease of understanding, you could do an array of characters. Each character holds a single digit 0 though 9. Do math on the arrays like you would by hand - add/subtract just requires you to carry or borrow digits between each element :

    Code:
    int carry = 0;
    for (int i = 0; i < ARRAY_LEN; i++)
    {
         int sum = op1[i] + op2[i] + carry;
         result[i] = sum % 10;
         carry = sum / 10;
    }
    if (carry)
       printf ("Overflow!");
    Subtraction is similar. Assuming you're not limited on time, multiplication is just repeated addition. Division is repeated subtraction with some hacks to get the remainder into a fractional form. Search for "arbitrary precision multiplication" and "arbitrary precision division" for quicker ways to do either.

    Using your idea of putting 5 decimal digits per int is similar - instead of 10 in my code you'll want to mod & divide by 10000. And doing this in fixed point will make things even more complex - you'll have to make a decision up front how many digits you need on either side of the decimal place. Sounds easy since you know the result is 2.x, but some of the intermediate math may produce results with a much larger integer portion.

    Are you sure you're understanding the question correctly? Normally these types of questions are to make you understand that even though x^N and N! individually will overflow, you can reuse part of the previous step to calculate it so that it doesn't. You just start with X, then each time through the loop multiply by x and divide by N instead of calculating x^N and N! each iteration. This won't give you 30 digits of precision but should give you close to the limits of precision of whatever floating point value you're using to hold the final result.

  10. #10
    Registered User
    Join Date
    May 2011
    Posts
    9
    This is supposed to make you use series like x[n] in order to divide a result into multiple parts and use functions to calculate the results and such.

    According to it,
    I need to find the specific part of the Maclaurin's Expansion and calculate it.

    So the X in e=1+x+(1/2!)*x and so on is always 1
    Giving us e=1+1+1/2!+1/3!+1/n! to calculate

    The program should calculate it in order of the N

    so If N is 1 it will calculate only the corresponding factorial division part;
    meaning that one part of the variable will hold the result of the calculation which will be x=1.00000000~ and the other will hold the actual sum up until now which is e=2.000000~

    For N=2
    x=1/2!, e=previous e+x

    for N=3
    x=1/3!, e=previous e+x

    each time the result is calculated, it needs to hold all the numbers after the dot into separate variables like x[1] x[2] x[3] until all the 30~35 digits are filled with them.
    so when printing out, in the case of N=2

    x[0].x[1]x[2]x[3]~
    should come out as
    0.50000000000000000000
    where x[0] should hold the value above the dot and x[1~3] would be holding the rest in 5 digits each.

    Well yeah Sorry if my explanation sucks but This is what its asking.
    And I cant use bigint as it defeats the purpouse

  11. #11
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    Quote Originally Posted by Brother_Sharp View Post
    This is supposed to make you use series like x[n] in order to divide a result into multiple parts and use functions to calculate the results and such.

    According to it,
    I need to find the specific part of the Maclaurin's Expansion and calculate it.

    So the X in e=1+x+(1/2!)*x and so on is always 1
    Giving us e=1+1+1/2!+1/3!+1/n! to calculate

    The program should calculate it in order of the N

    so If N is 1 it will calculate only the corresponding factorial division part;
    meaning that one part of the variable will hold the result of the calculation which will be x=1.00000000~ and the other will hold the actual sum up until now which is e=2.000000~

    For N=2
    x=1/2!, e=previous e+x

    for N=3
    x=1/3!, e=previous e+x

    each time the result is calculated, it needs to hold all the numbers after the dot into separate variables like x[1] x[2] x[3] until all the 30~35 digits are filled with them.
    so when printing out, in the case of N=2

    x[0].x[1]x[2]x[3]~
    should come out as
    0.50000000000000000000
    where x[0] should hold the value above the dot and x[1~3] would be holding the rest in 5 digits each.

    Well yeah Sorry if my explanation sucks but This is what its asking.
    And I cant use bigint as it defeats the purpouse
    I'm with tabstop that you're misunderstanding what's being asked. Can you copy and paste the exact text of the question?

    This part :
    meaning that one part of the variable will hold the result of the calculation which will be x=1.00000000~ and the other will hold the actual sum up until now which is e=2.000000~
    Makes me think you have two variables. One's the sum so far. The other is X = 1/n! for the previous value of n. To get the next sum, do

    Code:
    X /= n;
    sum += other;
    n += 1
    That is, each x[N] isn't a discrete set of digits that gets mushed together to form the final output, it's then next value you add to sum. Each x[N] has digits which contribute to change many of the digits instead of your idea that x[1] is digits 1-5 after the decimal point and the other x[] values have nothing at all to do with them.

    x[0] = 1 = 1.00000
    x[1] = 1 = 1.00000
    x[2] = 1/2 = 0.50000
    x[3] = 1/6 = 0.16667
    x[4] = 1/24 = 0.04167

    Note how both x[0] and x[1] change the integer part of the sum, and x[2] and x[3] both contribute to the digit right after the decimal point (the tenth's place) while x[3] and x[4] both contribute to change every digit in the fractional part (.16666 + 0.4167 = .20833 so every digit is different than before). You can't just line up x[0].x[1]x[2]x[3]x[4] and get 1.100000500001666704167, you have to add up each of the terms to get the final result.

    To say it a different way : read through the assignment and notice it isn't telling you to keep an array of X values, just one. It's telling you to keep track of exactly two values : the sum so far and 1/N! for the current value of N. Why do you need an array of 5 values plus a sum to hold two items?

    Also, does it specifically say 30-35 digits, or 30-35 iterations of the loop (i.e. N can go up to 30)? There's a big difference between the two. There's no reason to assume each iteration series will give you exactly one digit of accuracy. That's easy to see since doing 1 iteration gives you 1 as the result, so you need two iterations to get the first digit correct. If you're supposed to run 30 iterations to get 15 digits that'll fit in a double - no need for arbitrary precision numbers.

  12. #12
    Registered User
    Join Date
    May 2011
    Posts
    9
    After poking around this some more, it appears that this is done by using the following.
    Code:
    for (int J=0; J<8; J++)
    {
    if (J<7)
       {
       a[j+1]+=(a[j]%n)*10000
        }
    
    a[j]=a[j]/n
    }

    But I cant figure out what happens if you run that.
    I know that a[] is the one that holds the current decimal value up to 7 parts each having 5 digits.
    and that N is the current power which goes only up to 30.
    Still cant understand why this is the main part of this program
    Last edited by Brother_Sharp; 07-17-2011 at 04:01 AM.

  13. #13
    Registered User
    Join Date
    May 2011
    Posts
    9
    Er, the capital J is a typo, its supposed to be a lowercase J.

    Then I realized I needed the division part by N to be with the factorial so I edited it a bit when conpiled.

    So I tried running the above one but,
    On the 3rd power I keep getting 16666166661666616666 instead of 1666666666666666


    Disregard that too,
    I managed to get 166666666666666666 by using the factorial of N for both the Ns there.

    The other problem I have is, while doing the operations, it goes well till the 7th.
    Starting from the 8th and so on It wont continue without giving me negative numbers.

    for N=8
    It should be 00002480158730158730158730.
    Instead I get 00002 48015 -19220 -41904 30331 53015 -19220

    That is obviously due to int's limit and since at that part it does
    1936000000%40320
    in order to get a[3]'s value which then is 35200 which is then multiplied by 100000
    giving us a 3520000000/40320, though the value of a[3] exceeds the limit of integer, any way to fix this?
    I cannot use doubles or Bigints for this so if anyone has a workaround for this, it would be appreciated.
    Last edited by Brother_Sharp; 07-17-2011 at 05:12 AM.

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So everything is going great until you get to here:
    each time the result is calculated, it needs to hold all the numbers after the dot into separate variables like x[1] x[2] x[3] until all the 30~35 digits are filled with them.
    which (a) makes no sense and (b) directly contradicts everything before it. Therefore I suspect that sentence to be false.

  15. #15
    Registered User
    Join Date
    May 2011
    Posts
    9
    Thats what it says,
    Im supposed to make something that does different calculations and makes them up into one whole 30~35 digit number

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Cosine - Maclaurin Series
    By carrotcake1029 in forum C Programming
    Replies: 12
    Last Post: 12-07-2008, 12:20 PM
  2. Laplace Expansion
    By Leojeen in forum C Programming
    Replies: 7
    Last Post: 10-28-2008, 11:26 PM
  3. Macro expansion
    By onebrother in forum C Programming
    Replies: 1
    Last Post: 11-02-2007, 03:08 AM
  4. taylor series expansion
    By noor_mirza in forum C++ Programming
    Replies: 1
    Last Post: 10-23-2002, 10:02 PM
  5. Expansion
    By Generator in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 10-02-2001, 05:45 AM