Multiplying small numbers and getting Inf

  • Thread starter Thread starter jk22
  • Start date Start date
  • Tags Tags
    Numbers
Click For Summary

Discussion Overview

The discussion revolves around a programming issue related to numerical computations involving the sine function and exponentiation in C++. Participants are exploring why multiplying small numbers results in "Inf" at a certain iteration, specifically when using the sine function raised to a power that grows quadratically with the iteration count. The conversation touches on potential causes of overflow and the behavior of floating-point arithmetic in this context.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant notes that the code outputs "Inf" when multiplying a value smaller than 1, questioning if the issue arises from the square of the iteration variable exceeding the limits of the int type.
  • Another participant suggests that when the iteration variable reaches a certain value, its square may overflow, leading to negative values, which could cause the power function to produce large results when raising a small number to a negative power.
  • A different participant proposes changing the variable type from int to long to potentially resolve the overflow issue.
  • There is a clarification that the loop in the power function is controlled by the iteration variable, not its square, and that the call to the pow() function is indeed being used instead of the custom power function.
  • One participant expresses confusion about the mathematical implications of the sine function raised to a power, referencing a previous discussion about the limit of this expression and suggesting that numerical results may contradict analytical expectations.
  • Another participant challenges assumptions about finding significant values in the sequence of integers and discusses the behavior of the sine function near specific multiples of π, indicating that certain integers will yield significant results despite the overall trend towards zero.

Areas of Agreement / Disagreement

Participants express differing views on the cause of the "Inf" output, with some attributing it to integer overflow and others discussing the implications of floating-point arithmetic. There is no consensus on the resolution of the mathematical behavior of the sine function raised to a power, as some participants believe numerical results contradict theoretical expectations while others argue for the existence of significant values in the sequence.

Contextual Notes

Limitations include the potential for integer overflow in the computation of i*i, the behavior of floating-point arithmetic, and the assumptions made about the convergence of the sine function raised to increasing powers. The discussion also highlights the complexity of numerical versus analytical results without resolving these issues.

jk22
Messages
732
Reaction score
25
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:
#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:
Technology news on Phys.org
When you post code here, please use [code[/color]] and [/code[/color]] 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.
jk22 said:
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:
#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 ?
 
Mark44 said:
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.

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.
 
The loop is controlled by the value of i, not i*i.

... the power subroutine does not even enter the loop
?

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."
 
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.
 
Thanks I misregarding that I used the system function.

As I can see in this programm the sin(n)^{n^2} 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.
 
jk22 said:
Thanks I misregarding that I used the system function.

As I can see in this programm the sin(n)^{n^2} seems to tend towards 0,
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.
jk22 said:
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.
 
jk22 said:
Thanks I misregarding that I used the system function.

As I can see in this programm the sin(n)^{n^2} 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.
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.
 

Similar threads

  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
Replies
1
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 2 ·
Replies
2
Views
4K
  • · Replies 19 ·
Replies
19
Views
2K
  • · Replies 4 ·
Replies
4
Views
2K
Replies
2
Views
2K
  • · Replies 19 ·
Replies
19
Views
3K
Replies
2
Views
7K