Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Multiplying small numbers and getting Inf

  1. Nov 11, 2013 #1
    At approx. step 46000 the following code puts "Inf" out, but I can't understand why since it multiplies by itself a value smaller than 1. The sin is ok, but the loop for the power fails :

    Code (Text):
    #include<stdio.h>
    #include<math.h>

    double power(double x, int n)
    {
        double result=1.0;
        for(int i=0;i<n;i++)
            result*=x;
        return(result);
    }

    int main(void)
    {
        int nsub=800;
        int iter=50000;
        double sum=0.0;

        int *distr=new int[nsub];

        for(int i=1;i<iter;i++)
        {
            double val=pow(sin((double)i),i*i);
            int subn=(int)(val*(double)nsub/2.0);

            distr[subn+nsub/2]++;
            if(fabs(val)>1.0) printf("%d %lf %lf\n",i,sin((double)i),val);
            sum+=val;
        }
        printf("%lf\n",sum);

        FILE *seriesout=fopen("series.out","w");

        for(int i=0;i<nsub;i++)
            fprintf(seriesout,"%lf %lf\n",2*(double)i/(double)nsub-1.0,(double)distr[i]/(double)iter);

    }
    Is it because the i squared is too big for the int type ?
     
    Last edited by a moderator: Nov 11, 2013
  2. jcsd
  3. Nov 11, 2013 #2

    Mark44

    Staff: Mentor

    When you post code here, please use [code] and [/code] tags. These tags preserve your indentation, which makes your code easier to understand. I have done this below.

    As to your problem, I suspect that when i = 46000, i*i is too large for a signed int. When this happens, the result becomes negative. Raising a number between -1 and 1 to a negative power results in a very large number.

    An int is typically stored in four bytes. For your system, I'll bet that "int" means "signed int." The largest signed int would be 231 - 1 = 2,147,483,647. When i is 46,000, i2 is 2,116,000,000, which is pretty close to the maximum signed integer.

    Changing from int to long might fix your problem.
     
  4. Nov 11, 2013 #3
    Thanks, I'll try with unsigned int.

    But if let say i*i becomes a negative number, the power subroutine does not even enter the loop so shouldn't the result be 1.0 ? This subroutine power does not compute negative powers.
     
  5. Nov 11, 2013 #4

    Mark44

    Staff: Mentor

    The loop is controlled by the value of i, not i*i.

    ???

    The call to pow() is inside the loop. The loop runs 49,999 times. When i is large enough (a little above 44,000) i * i becomes negative due to overflow. Your compiler should have some documentation about the pow() function.

    BTW, C and C++ programmers pretty much never use the term "subroutine."
     
  6. Nov 11, 2013 #5

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    You are calling the system function pow() rather than your power(). That's a good thing. You could fix your program so it calls your function instead of pow(), fix your calculation so it computes i*i correctly, and you fix your function so it takes a long instead of an int. Don't do that. Your program would take an hour or so to run if you were calling your function.

    There is a fast way to compute xn that doesn't use pow(). x8 can be done with only three multiplies rather than eight. x16, with only four multiplies. x32, with only five multiplies. Done properly, the number of multiplications will grow logarithmically rather than linearly.
     
  7. Nov 12, 2013 #6
    Thanks I misregarding that I used the system function.

    As I can see in this programm the [tex]sin(n)^{n^2}[/tex] seems to tend towards 0, but mathematically we saw in another thread that the limit should not exist : https://www.physicsforums.com/showthread.php?t=715871&page=2

    Hence, for sin power n squared, there should exist a subsequence not tending towards 0.

    I suppose however the numerical result to be correct, hence there should be an error in the mathematical derivation. I don't know in which section I should write this since it's a comparison between numerical results and analytical ones.
     
  8. Nov 12, 2013 #7

    Mark44

    Staff: Mentor

    What does this mean? Is n being raised to the power n2, or is sin(n) being raised to that power?

    I could probably figure out your intent by looking at your code again, but I shouldn't need to do that.
     
  9. Nov 12, 2013 #8

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    The error is yours. You are assuming two key things here, both of them false:
    • You are assuming you are going to find it by looking at the sequence of integers from 1 to 50,000. You aren't.
    • You are assuming that you are going to find this sequence using a computer's built-in floating point arithmetic. You aren't.
    This is a problem of behavior as n grows very large. 50,000 is not a large number. You missed, for example, n=51819, 52174, 156167, and 260515. There are lots of integers where sin(n) is very close to ±1. A lot of those candidates are going to go to near zero upon raising sin(n) to the n2 power, but some won't. (I picked four that won't. Try them.)

    Here's what happens with the partial sums of ##\sum_{n=1}^{\infty} (\sin n)^{(n^2)}##. It's going to bounce around some but then appear to stabilize to about 1.926. Then, blam, you come across n=51819 and n=52174. Then a slight jump when you hit n=156167. Then a huge jump when you hit n=260515. You'll keep getting these seemingly random points where the partial sums jump. That's because you hit a number n that is very close to pi/2 or 3*pi/2, modulo 2*pi.

    If n is very close to pi/2 (modulo 2*pi), then sin(n) is close to 1, so sin(n)(n2) is going to be positive. If n is is very close to 3*pi/2 (modulo 2*pi), then sin(n) is close to -1, so sin(n)(n2) is going to be positive if n is even, negative if n is odd. On average, you'll see three significant positive values of sin(n)(n2) to every significant negative value amidst the sea of values that are extremely close to zero. The spacing between these significant values will increase, but they're always going to be there. The series grows without bound because of that 3:1 positive to negative ratio.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Multiplying small numbers and getting Inf
Loading...