Issue finding euler's number in java - java

i have to find e, which is 1/0! + 1/1! + 1/2! + 1/3!... + 1/n! given n as a parameter and i'm having trouble getting the correct answer.
public double Factorial(int n) {
long fact = 1;
for (int i = 1; i <= n; ++i) {
fact *= i;
}
return fact;
}
public double euler(int n) {
double y = 0;
for (int x = 0; x <= n; x++) {
double e = 1 / Factorial(n);
y = y + e;
}
return y;
when i input 10, this outputs 2.7557319223985893E-6 when i should be getting 2.7182818011463845. i ran through the code a few times but i can't figure out the issue. any help is appreciated.

The answer given in the comments addresses the problem. And since you have the algorithm down you may be interested in the following:
A factorial method is not necessary. Since each subsequent value of n! is n! * (n+1) you can work it into your main loop as follows.
// initialize fact to 0!
double fact = 1;
// first Euler term 1/0!
double y = fact;
for (int x = 1; x <= n; x++) {
// next factorial
fact *= x;
// subsequent terms
y += (1 / fact);
}
System.out.println(y);
Prints
2.7182818011463845
And Euler's number is also the limit of (1 + r)(1/r) as r approaches 0.
double r = .000000001;
System.out.println(Math.pow(1 + r, 1/r));
2.71828205201156

Related

What is wrong with this source code for sine?

I'm quite good enough with Java syntax and just decided to put it to work by creating a code for sine based on an algorithm I created earlier. I know Math.sin helps you evaluate sine but I just for the fun, decided to go on an create my own source code.
However, angles between 60° and 120° and also between 240° and 300° give wrong answers and I have no idea why. Could someone please help me find the error? I've tried everything to detect it but failed.
import java.util.Scanner;
public class Sine {
public static void main(String[] args) {
// This code solves sine according yo the general expansion of sine
// sin x = x - x³/3! +x^5/5! - x^7/7! +...
Scanner scanner = new Scanner(System.in);
double answer = scanner.nextDouble();
scanner.close();
answer = simplify(answer);
answer = converttoradian(answer);
answer = continued(answer);
System.out.println(answer);
}
// This Makes all the angles that are more than 360
// To become less than 360 and Generates the simplified
// Angles for obtuse and reflex angles
static double simplify(double x) {
if (x >= 360) {
x = x - 360;
return simplify(x);
}
else if (x <= -360) {
x = x + 360;
return simplify(x);
}
else if (x > 90 && x <= 270) {
x = 180 - x;
return x;
}
else if (x >= 270) {
x = x - 360;
return x;
}
else if (x <= -90 && x > -270) {
x = -x - 180;
return x;
}
else if (x <= -270) {
x = x + 360;
return x;
}
else {
return x;
}
}
// Simple enough and explains itself
// Converts the angles to radian
static double converttoradian(double d) {
d *= Math.PI;
d /= 180.0;
return d;
}
// This Method about to open generates each term and adds them together
// The number of terms solved in this case is 33
static double continued(double d) {
double answer = 0.0;
int index = 1;
double one = d;
for (int i = 0; i < 33; i++) {
double result = 0.0;
for (int x = 1; x < index; x++) {
d = d * one;
}
long here = factorial(index);
result = d / here;
if ((index - 1) % 4 == 0) {
answer = answer + result;
index = index + 2;
}
else {
answer = answer - result;
index = index + 2;
}
}
return answer;
}
// Evaluates factorials
static long factorial(int n) {
long one = 1;
long m = (long) n;
if (m == 0 || m == 1) {
one = 1;
return one;
}
else {
while (m > 1) {
one *= m;
m--;
}
return one;
}
}
}
There was a lot going on in your program and some unnecessary code. You were on the right track, though. I made some changes to simplify the calculations. You should be able to follow them.
Specifically.
Alternate the sign. Start out with sign = 1, then set sign = -sign for subsequent terms.
For the denominator and factorial, I just used the for loop, starting at 1 and incrementing by 2 to get 1,3,5,7
For powers of the same value, I just multiplied d by a dSquared constant to achieve the same.
I rewrote the factorial to make it simpler.
To reduce large values of d I just used the remainder operator to get them less than 360.
I added some print statements to show calculation progress and to ensure things were working correctly.
And finally, the maximum factorial that will fit in a long is 20!. After that they turn negative due to overflow. So the number of terms needed to be reduced.
public class Sine {
public static void main(String[] args) {
// This code solves sine according yo the general expansion of sine
// sin x = x - x³/3! +x^5/5! - x^7/7! +...
for (double degrees = 0; degrees < 700; degrees += 17) {
double simplified_degrees = simplify(degrees);
System.out.println("simplified_degrees = " + simplified_degrees);
double radians = converttoradian(simplified_degrees);
System.out.println("radians = " + radians);
double sin = continued(radians);
System.out.println(sin);
System.out.println(Math.sin(radians));
System.out.println("------------------------------------------");
}
}
// This Makes all the angles that are more than 360
// To become less than 360 and Generates the simplified
// Angles for obtuse and reflex angles
static double simplify(double x) {
x = x % 360;
return x;
}
// Simple enough and explains itself
// Converts the angles to radian
static double converttoradian(double d) {
return Math.PI / 180. * d;
}
// This Method about to open generates each term and adds them together
// The number of terms solved in this case is 33
static double continued(double d) {
double result = 0;
double sign = 1;
double dSquared = d * d;
int pow = 1;
for (int pow = 1; pow < 21; pow += 2) {
long fact = factorial(pow);
System.out.println("d = " + d + ", fact = " + fact + ", pow = " + pow
+ ", sign = " + sign);
result = result + (d / fact) * sign;
d *= dSquared; // effective powers 3, 5, 7,9
sign = -sign; // alternate sign for every other term
}
return result;
}
// Evaluates factorials
static long factorial(int n) {
if (n == 0 || n == 1) {
return 1;
}
long fact = 1;
for (long i = 2; i <= n; i++) {
fact *= i;
}
return fact;
}
}

I'm attempting to write a Taylor-expansion calculator in Java, but the program doesn't calculate correctly

I'm trying to create a Java program that will calculate a cosine value with the following equation:
The code to my program is located below. I don't appear to have any errors in my program however no matter what values that I set x and k to, I get the answer Infinity and I cannot figure out what I've done wrong.
The way that the code works, is that the console asks you for a value for x and then a value for k. Then the idea is to have Java compare the result of the equation (the method cosine in the script) with the Math.cos() function.
The method cosine is split up into two parts, cosinenumerator and cosinedenominator which is then divided with each other to become cosineresult at the end.
The loop for cosinedenominator is supposed to emulate a "factorial" in the equation.
Any help would be greatly appreciated.
import java.util.Scanner;
public class Cosine {
public static void main(String[] args) {
Scanner consolecosine = new Scanner(System.in);
System.out.println("Enter x value:");
double x = consolecosine.nextDouble();
System.out.println("Enter k value:");
int k = consolecosine.nextInt();
double cosineresult = cosine(x, k);
System.out.println("Using the Math.cos function yields: " + Math.cos(90));
System.out.println("Using the Taylor expansion equation yields: " + cosineresult);
}
public static double cosine(double x, int k) {
double cosineresult = 0;
double cosinenumerator = 0;
double cosinedenominator =0;
int i = 0;
int j = 0;
for(i = 0; i <= k; i++) {
cosinenumerator += Math.pow((-1),i) * Math.pow(x, (2*i));
}
for(j = 0; j <= (2*i); j++) {
cosinedenominator *= (2*j);
}
cosineresult = cosinenumerator / cosinedenominator;
return cosineresult;
}
}
Here's a working version (note that x is in radians; not degrees):
cosine(Math.PI, 15) yields -1.0000000000000002, which is about right.
public static double cosine(double x, int k) {
double cosineresult = 0;
double cosinedenominator = 1; // initial value 0! = 1; overflows at k = 86
int j = 2; // next multiplier in denominator factorial (skip 1)
for (int i = 0; i <= k; i++) {
double cosinenumerator = Math.pow((-1),i) * Math.pow(x, (2 * i));
// Continue calculation of factorial from last value
while (j <= 2 * i) {
cosinedenominator *= j++;
}
cosineresult += cosinenumerator / cosinedenominator;
}
return cosineresult;
}

What causes Java version Random walk doesn't converge to expected value?

Basically, I implemented a Random walk program in Java. And I know the distance should converge to l * (n ^ 0.5)(l is the step length, n is the total steps). If let l equals to 1, then d = n ^ 0.5 or in other words: d = sqrt(n).
But, strangly, although I cannot find any error in my code, it just converges to unexpected value. For example, given l = 1, n = 100, d should converge to 10, but actually it converges to 8.86 after 1000000 times experiments.
Here is my code:
public class RandomWalk {
private int x = 0;
private int y = 0;
private final Random random = new Random();
private void move(int dx, int dy) {
x += dx;
y += dy;
}
private void randomWalk(int m) {
for (int i = 0; i < m; i++)
randomMove();
}
private void randomMove() {
boolean xOry = random.nextBoolean();
boolean plusOrminus = random.nextBoolean();
int delta = plusOrminus ? 1 : -1;
int dx = xOry ? delta : 0, dy = xOry ? 0 : delta;
move(dx, dy);
}
public double distance() {
return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}
public static double randomWalkMulti(int m, int n) {
double totalDistance = 0;
for (int i = 0; i < n; i++){
RandomWalk walk = new RandomWalk();
walk.randomWalk(m);
totalDistance += walk.distance();
}
return totalDistance/n ;
}
}
I've thought some possiblities. First I think it may be caused by that the generated boolean by random has bias. Second I think it may be caused by float precision lost. But as this is just a very simple use case, I don't think these two situations are possible.
Could any one tell me why it doesn't work as expected?
I don't think it's true that the distance should average out to √n. According to https://math.stackexchange.com/questions/103142/expected-value-of-random-walk, the square of the distance should average out to n, but that's not the same thing (since the average of the square roots of a set of numbers is not the same as the square root of their average).

Find Number Of Square Roots Between Two Numbers

I have written this function for finding the number of Square Roots between two numbers (inclusive).
static int FindRoot(int no1, int no2) {
int res = 0;
for (int x = no1; x <= no2; x++) {
for (int y = 1; y <= no2; y++) {
if (y * y == x)
res++;
}
}
return res;
}
This will work fine, but I was thinking about it's performance.
Because in this case the inner For loop will execute from starting position(1), so it'll take time if someone passes a large number range to the method.
So, my question is:
Is there any other way i can find this with better performance?
P.S.- I can't use Math.sqrt() function
static int FindRoot(int no1, int no2) {
int res = 0;
int x = 0;
// Ignore squares less than no1
while(x*x < no1) {
x++;
}
// Count squares up to and including no2
while(x*x <= no2) {
res++;
x++;
}
return res;
}
You can get away with having a single for loop by getting rid of the outer loop
static int findRoot(int lo, int hi) {
int numRoots = 0;
for (int x = 0, x2 = 0; x2 <= hi; x++, x2 = x * x) {
if (x2 >= lo) {
numRoots++;
}
}
return numRoots;
}
here you effectively just do your inner loop once, incrementing numRoots when x2 (x-squared) is between lo and hi, and terminating the loop when x2 is greater than hi (instead of when x is greater than hi like in your code).
It'll work as well.
static int FindRoot2(int no1, int no2) {
int res = 0;
int inner=1;
for (int x = no1; x <= no2; x++) {
for (int y = inner; y <= no2; y++) {
if (y * y == x)
{
inner=y;
res++;
}
}
}
return res;
}
In this case inner loop will not start executing from 1.
There are many reasons why your current algorithm is ineffecient, but the biggest one is that the inner for loop is not necessary.
The idea behind the algorithm you're looking for, is to start at the lowest perfect square higher than or equal to no1, then go to the next perfect square and the next and the next, keeping track of how many you hit, until the perfect square you're on is higher than no2.
static int FindRoot(int no1, int no2) {
int res = 0;
int x = 1;
// This loop gets x to the first perfect square greater than
// or equal to no1
while( (x * x) < no1 ) {
x++;
}
// This loop adds 1 to res and increases x
// as long as x^2 is less than or equal to no2
for(; (x * x) <= no2; x++, res++) { }
return res;
}

Java Nested Loops Issue

so I've been working on this code for a while now, and I've reached a standstill. It's a project for school and it came in two parts, the first part was no issue at all.
A drunkard begins walking aimlessly, starting at a lamp post. At each time step, the drunkard forgets where he or she is, and takes one step at random, either north, east, south, or west, with probability 25%. How far will the drunkard be from the lamp post after N steps?
Write a program RandomWalker.java that takes an integer command-line argument N and simulates the motion of a random walker for N steps. After each step, print the location of the random walker, treating the lamp post as the origin (0, 0). Also, print the square of the final distance from the origin.
My code for this part of the problem was:
import java.util. *;
import java.math. *;
public class RandomWalker {
public static void main(String args[]){
int N = Integer.parseInt(args[0]);
Random rand = new Random();
int x = 0;
int y = 0;
int XorY;
int dist;
int count =0;
while(count<N){
XorY = rand.nextInt(2);
dist = rand.nextInt(2);
if(XorY==0){
if(dist==0)
dist = -1;
x += dist;
System.out.println("("+x+", " +y+")");
}
else{
if(dist==0)
dist = -1;
y += dist;
System.out.println("("+x+", " +y+")");
}
count ++;
}
System.out.println("Squared Distance = " + (x*x + y*y));
}
}
For the second part of the problem-
Write a program RandomWalkers.java that takes two command-line arguments N and T. In each of T independent experiments, simulate a random walk of N steps and compute the squared distance. Output the mean squared distance (the average of the T squared distances.)
% java RandomWalkers 100 10000
squared distance = 101.446
% java RandomWalkers 100 10000
mean squared distance = 99.1674
% java RandomWalkers 200 1000
mean squared distance = 195.75
The code I came up with is-
import java.util.*;
import java.math.*;
public class RandomWalkers {
public static void main(String args[]) {
Random rand = new Random();
int N = Integer.parseInt(args[0]);
int T = Integer.parseInt(args[1]);
double avgDist =0;
int stepCount =0;
int trialCount =0;
int x = 0;
int y = 0;
int XorY;
int dist;
while(trialCount<T){
while(stepCount<N){
XorY = rand.nextInt(2);
dist = rand.nextInt(2);
if(XorY==0){
if(dist==0)
dist = -1;
x += dist;
}
else{
if(dist==0)
dist = -1;
y += dist;
}
stepCount ++;
}
avgDist += ((x*x) + (y*y));
trialCount++;
}
System.out.println("Mean Squared Distance = " + avgDist/(double)trialCount);
}
}
I have been stumped here for a really long time, the code compiles and runs but it seems that all it is giving me is a single trial value, and not the desired average. Any help is appreciated, thank you very much. (Also sorry for the improper formatting, I am new here and tried my best).
The solution with the nested while loop inside the for loop is shown below. You have to reset the x, y and distance variables after each trial. Or, even better, to define and initialize them to 0 at the beginning of the for loop, like so:
public class RandomWalkers {
public static void main(String[] args) {
int r = Integer.parseInt(args[0]);
int trials = Integer.parseInt(args[1]);
double steps = 0.0;
for (int j = 0; j < trials; j++) { // run one experiment
int x = 0;
int y = 0;
int distance = 0;
while (distance < r) { // simulate one random walking
double i = Math.random();
if (i < 0.25) {
y += 1;
distance = Math.abs(x) + Math.abs(y);
steps += 1;
}
if (i >= 0.25 && i < 0.5) {
x += 1;
distance = Math.abs(x) + Math.abs(y);
steps += 1;
}
if (i >= 0.5 && i < 0.75) {
y -= 1;
distance = Math.abs(x) + Math.abs(y);
steps += 1;
}
if (i >= 0.75 && i < 1) {
x -= 1;
distance = Math.abs(x) + Math.abs(y);
steps += 1;
}
}
}
System.out.println("average number of steps = " + steps / trials);
}
}

Categories

Resources