finding the sum of the sreies, using java - java

the question is to find the sum of this series
series
i used this code to solve it , but im not quite sure the logic is correct.
the noofterms is how many terms are going to be added
and x is the number that will be assigned to the variable.
does the logic seem correct?
public static double sumOfSeries(double x, int noofterms){
double evennumbers=1;
double oddnumbers=1;
double result=1;
// since the power of x starts from 1 , we start i from 1 and increment by 2
for (int i=1; i<noofterms; i+=2 ){
// we reset starting numbers so we start from them everytime
evennumbers = 1;
oddnumbers = 1;
// everytime the number increases by 2 when it is smaller than i+1
// ex when its equal to 2 , j = 3 , j+1 = 4 so it increments by 2
// when its 4 , j = 5 , j+ 1 = 6 , it increments
for (int j=2; j<=i+1; j+=2){
// multiply by increments of 2
evennumbers= evennumbers * j;
}
// it starts from 1 and increments by 2 so it goes like 1,3,5
for (int z=1; z<=i; z+=2){
oddnumbers = oddnumbers * z;
}
result*=((Math.pow(x, (double)i)) / (double)i) + (oddnumbers/evennumbers);
}
return result;
}

You can do it better. Note that numerators and denominators form two sequences, so you can keep previous terms to efficiently make computations, this will look like this :
long even = 1;
long odd = 1;
double result = x;
for(long i = 1; i < noofterms; i++)
{
even *= 2 * i;
odd *= 2 * i - 1;
double oper = Math.pow(x, (double)(2 * i + 1)) / (double)(2 * i + 1);
result += (double)even / (double)odd * oper;
}
You can improve by using logarithms because even and odd will grow very fast and will lead to overflows :
double even = 0.0;
double odd = 0.0;
double result = x;
double logx = Math.log(x);
for(long i = 1; i < noofterms; i++)
{
even += Math.log((double)(2 * i));
odd += Math.log((double)(2 * i - 1));
double oper = logx * (2 * i + 1) - Math.log((double)(2 * i + 1));
result += Math.exp(even - odd + oper);
}
EDIT: only one sequence could also be computed : p *= (double)(2*i)/(2*i-1). Then the log trick is not useful.

Related

How to write a Taylor series as a function

I have to write a Taylor series until the 16th element that calculates sin and compare the values returned values with Math.sin. Well , everything works fine until the last time when instead of 0.00000 i get 0.006941.Where is my error and if somebody have an idea how to write this in a more professional way I would be very happy.
import java.text.NumberFormat;
import java.text.DecimalFormat;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
NumberFormat formatter = new DecimalFormat("#0.000000");
double val[] = {0, Math.PI / 3, Math.PI / 4, Math.PI / 6, Math.PI / 2, Math.PI};
for (int i = 0; i < val.length; i++) {
System.out.println("With Taylor method: " + formatter.format(Taylor(val[i])));
System.out.println("With Math.sin method: " + formatter.format(Math.sin(val[i])));
}
}
public static double Taylor ( double val){
ArrayList<Double> memory = new ArrayList<Double>();
double row = val;
for (int i = 0, s = 3; i < 16; i++, s = s + 2) {
double mth = Math.pow(val, s);
double result = mth / factorial(s);
memory.add(result);
}
for (int i = 0; i < 16; i++) {
if (i % 2 == 0) {
double d = memory.get(i);
row = row - d;
} else {
double d = memory.get(i);
row = row + d;
}
}
return row;
}
public static long factorial ( double n){
long fact = 1;
for (int i = 2; i <= n; i++) {
fact = fact * i;
}
return fact;
}
}
Your math is correct, but your factorials are overflowing once you get to calculating 21!. I printed out the factorials calculated.
factorial(3) = 6
factorial(5) = 120
factorial(7) = 5040
factorial(9) = 362880
factorial(11) = 39916800
factorial(13) = 6227020800
factorial(15) = 1307674368000
factorial(17) = 355687428096000
factorial(19) = 121645100408832000
factorial(21) = -4249290049419214848 // Overflow starting here!
factorial(23) = 8128291617894825984
factorial(25) = 7034535277573963776
factorial(27) = -5483646897237262336
factorial(29) = -7055958792655077376
factorial(31) = 4999213071378415616
factorial(33) = 3400198294675128320
It appears that your raising val to ever higher powers isn't significant enough to make a difference with the overflow until you get to the highest value in your array, Math.PI itself. There the error due to overflow is significant.
Instead, calculate each term using the last term as a starting point. If you have the last value you entered into memory, then just multiply val * val into that value and then divide the next two numbers in sequence for the factorial part.
That's because memory.get(i) is equal to memory.get(i - 1) * (val * val) / ((s - 1) * s). This also makes your calculation more efficient. It avoids the multiplication repetition when calculating the numerator (power part) and the denominator (the factorial calculation). This will also avoid the overflow which results from how you calculated the denominator separately.
My implementation of this idea substitutes this for the first for loop:
double mth = val;
for (int i = 0, s = 3; i < 16; i++, s = s + 2) {
mth = mth * val * val;
mth = mth / ((s - 1) * s);
memory.add(mth);
}
and places
double row = val;
between the for loops, to ensure that the first term is the initial sum as you had it before. Then you don't even need the factorial method.
This this I get 0.000000 for Math.PI.

Use processing solve: S=1+1/2-1/3+1/4...+1/99-1/100 [duplicate]

This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 4 years ago.
I want to solve this math question in processing:
S=1+1/2-1/3+1/4...+1/99-1/100.
Here is my code (don't know why it doesn't work. I suppose it will print one number in the console, but it comes out a series of natural numbers):
float N = 0;
float T = 0;
int i = 1;
void draw() {
for (i = 1; i < 100; i += 2) {
N = N + 1 / i;
T = T + 1 / (i + 1);
}
println(N - T);
}
First off, draw() runs every frame. Use setup() instead, it runs once.
Second, dividing ints results in an int. Go ahead, do println(1/i) and see the magic.
Third, always google around for some time before going to SO. You'll learn more by finding it out yourself. And this was very solvable with google and a little effort ;)
working code:
float N = 0;
float T = 0;
int i = 1;
void setup() {
for (i = 1; i < 100; i += 2) {
N = N + 1.0 / i;
T = T + 1.0 / (i + 1);
}
println(N - T);
}
1 / i is a division expression between two integers, the result of which will be an int obtained by truncating the fraction part of the result. Since you are calculating float you can resolve it by using a 1f float literal
for (int i = 1; i < 100; i += 2) {
N = N + 1f / i;
T = T + 1f / (i + 1);
}
However your code currently counts the following:
Consider i = 1 for which you get T = 0.5 which you later subtract from N while you should be adding it as per your problem statement. One way to sole it is to write the code as:
float sum = 1;
for (int i = 2; i <= 100; i++) {
float term = 1f / i;
if (i % 2 != 0) {
term *= -1;
}
sum += term;
}
System.out.println(sum);

Maximum value of int breaking my for loop?

I was attempting to solve this morning's Codeforces problem Div 2C: http://codeforces.com/contest/716/problem/C
This problem has the potential to loop up to 100,000 times so the parameter here can be up to 100,000. Loop seems to break when passing in 100,000 (and possibly earlier) and i is declared as an int:
public void solve(int a) {
double x = 2;
double y = 0;
double n = 0;
double target = 0;
double lcm = 0;
for (int i = 1; i <= a; i++) {
lcm = (i + 1) * i;
y = ((lcm * lcm) - x) / i;
n = (y * i) + x;
if (Math.sqrt(n) % (i + 1) == 0) {
x = Math.sqrt(n);
String answer = String.format("%.0f", y);
System.out.println("this is i: " + i);
System.out.println(answer);
}
}
}
Here is the relevant output:
this is i: 46337
99495281029892
this is i: 46338
99501722706961
this is i: 46340
99514606895203
this is i: 65535
32769
Doing a quick search on Stack overflow shows that the number 65535 is associated with a 16-bit unsigned int, but java uses 32bit ints. Changing the type to double works, as does simply looping 100,000 times and printing without the code logic. I understand that 100,000^2 IS above the maximum int limit, but this value is never stored as an int in my code. What's going on here?
The following line generates an out of bounds int before converting the result to double:
lcm = (i + 1) * i;
The above is essentially the same as:
lcm = (double)((i + 1) * i);
or
int temp = (i + 1) * i;
lcm = (double) temp;
Instead try (first converting to double and then taking what is similar to a square):
lcm = (i + 1.0) * i;

I have some questions regarding this tracing

public class Task {
public static void main(String args[]) {
int x = 0, p = 0, sum = 0;
p = 1;
x = 2;
double q;
sum = 0;
while (p < 12) {
q = x + p - (sum + 5 / 3) / 3.0 % 2;
sum = sum + (x++) + (int) q;
System.out.println(sum);
if (x > 5)
p += 4 / 2;
else
p += 3 % 1;
}
sum = sum + p;
System.out.println(sum);
}
}
While proceeding to line 12 (sum = sum + (x++) + (int)q;) i thought sum should be 5 but actually the output is 4. I tried line 12 in the interactions pane and indeed saw that sum=4. I don't get it. Shouldn't x++ yield 3 (x=2) and if this gets added to (int) q ( double q gave me sth like 2.666666), i should be getting 5. Can someone explain to me what happened?
Additionally,after getting my first output, how should I proceed?
The next condition is:
if (x > 5)
p += 4 / 2;
else
p += 3 % 1;
since x<5, i should go for the else condition, right?
My last question is that, after using p += 3%1, my p still remains 1, so do i return back to this loop (since p<12) or do I get out of this loop and proceed to line19? I'm not sure what to do.
In line 12 you are using post increment (x++). You should use pre increment ++x.
Post increment puts the current value of x in your statement, then increases x.
Pre increment initially increases x and after that puts result into your statement.
At your first time, 3%1=0
p +=3%1 => p+=0 thats why p still remains 1

Split number into several numbers

I wrote a programm to get the cross sum of a number:
So when i type in 3457 for example it should output 3 + 4 + 5 + 7. But somehow my logik wont work. When i type in 68768 for example i get 6 + 0 + 7. But when i type in 97999 i get the correct output 9 + 7 + 9. I know that i have could do this task easily with diffrent methods but i tried to use loops . Here is my code: And thanks to all
import Prog1Tools.IOTools;
public class Aufgabe {
public static void main(String[] args){
System.out.print("Please type in a number: ");
int zahl = IOTools.readInteger();
int ten_thousand = 0;
int thousand = 0;
int hundret = 0;
for(int i = 0; i < 10; i++){
if((zahl / 10000) == i){
ten_thousand = i;
zahl = zahl - (ten_thousand * 10000);
}
for(int f = 0; f < 10; f++){
if((zahl / 1000) == f){
thousand = f;
zahl = zahl - (thousand * 1000);
}
for(int z = 0; z < 10; z++){
if((zahl / 100) == z){
hundret = z;
}
}
}
}
System.out.println( ten_thousand + " + " + thousand + " + " + hundret);
}
}
Is this what you want?
String s = Integer.toString(zahl);
for (int i = 0; i < s.length() - 1; i++) {
System.out.println(s.charAt(i) + " + ");
}
System.out.println(s.charAt(s.length()-1);
The problem with the code you've presented is that you have the inner loops nested. Instead, you should finish iterating over each loop before starting with the next one.
What's happening at the moment with 68768 is when the outer for loop gets to i=6, the ten_thousand term gets set to 6 and the inner loops proceed to the calculation of the 'thousand' and 'hundred' terms - and does set those as you expect (and leaving zahl equal to 768 - notice that you don't decrease zahl at the hundreds stage)
But then the outer loop continues looping, this time with i=7. With zahl=768, zahl/1000 = 0' so the 'thousand' term gets set to 0. The hundred term always gets reset to 7 with zahl=768.
The 97999 works because the thousand term is set on the final iteration of the 'i' loop, so never gets reset.
The remedy is to not nest the inner loops - and it'll perform a lot better too!
You should do something like this
input = 56789;
int sum = 0;
int remainder = input % 10 // = 9;
sum += remainder // now sum is sum + remainder
input /= 10; // this makes the input 5678
...
// repeat the process
To loop it, use a while loop instead of a for loop. This a great example of when to use a while loop. If this is for a class, it will show your understanding of when to use while loops: when the number of iterations is unknown, but is based on a condition.
int sum = 0;
while (input/10 != 0) {
int remainder = input % 10;
sum += remainder;
input /= 10;
}
// this is all you really need
Your sample is a little bit complicated. To extract the tenthousand, thousand and the hundreds you can simply do this:
private void testFunction(int zahl) {
int tenThousand = (zahl / 10000) % 10;
int thousand = (zahl / 1000) % 10;
int hundred = (zahl / 100) % 10;
System.out.println(tenThousand + "+" + thousand + "+" + hundred);
}
Bit as many devs reported you should convert it to string and process character by character.

Categories

Resources