The problem is to determine the number of hours required before the second method becomes more beneficial than the first. I've been looking at this all day and don't know why I can't get it to print.
public class BestMethod{
public static void main(String[] args){
double earnings1 = 10.00;
double earnings2 = 0.10;
double totalHours1 = 0;
double totalHours2 = 0;
double x = 0;
double y = 0;
for (int i = 1; i <= 10; i++)
{
totalHours1++;
x = totalHours1 * earnings1;
totalHours2++;
earnings2 *= 1;
y = (earnings2 * 1) * 2 + earnings2;
}
if (y > x){
System.out.println ("It will take the second method " + totalHours2 + " hours before it becomes more beneficial than the first method ");
}
}
}
Based on your code, the value of earnings1 and earnings2 are remaining the same.
After the first iteration (i = 1) how values are changing (use pen and paper)
totalHours1 = 1.0, totalHours2 = 1.0, x = 10.0 and y = 0.30000000000000004
After completing the loop (i = 10)
totalHours1 = 10.0, totalHours2 = 10.0, x = 100.0 and y = 0.30000000000000004
So, the value of y is less than the value of x and the condition is going to false.
So, (in case if you want to) print the value use this in your program if (y < x) or you have to change the mathematical (calculation) method.
Related
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.
First I would apologize if my question seems not clear.
I want output to be the largest possible number from user input. Example:
input: x = 0; y = 9; z = 5;
output: 950
I tried something like the below code.
import java.util.Scanner;
class LargestOfThreeNumbers{
public static void main(String args[]){
int x, y, z;
System.out.println("Enter three integers ");
Scanner in = new Scanner(System.in);
x = in.nextInt();
y = in.nextInt();
z = in.nextInt();
if ( x > y && x > z )
System.out.println("First number is largest.");
else if ( y > x && y > z )
System.out.println("Second number is largest.");
else if ( z > x && z > y )
System.out.println("Third number is largest.");
}
}
The code above will print something like: The seconde number is largest. That is correct the way I define the conditional statements. But how do I get 950 as final result? I know some logic is required here but my brain doesn't seem to produce it.
Your help is appreciated.
You could do something like this to print the numbers in order:
// make an array of type integer
int[] arrayOfInt = new int[]{x,y,z};
// use the default sort to sort the array
Arrays.sort(arrayOfInt);
// loop backwards since it sorts in ascending order
for (int i = 2; i > -1; i--) {
System.out.print(arrayOfInt[i]);
}
A solution using java 8 IntStream:
int x = 0, y = 9, z = 5;
IntStream.of(x,y,z).boxed().sorted( (i1,i2) -> Integer.compare(i2, i1)).forEach( i -> System.out.print(i));
You can find the maximum with successive calls to Math.max(int, int) and the minimum with calls to Math.min(int, int). The first number is the max. The last is min. And the remaining term can be determined with addition of the three terms and then subtraction of the min and max (x + y + z - max - min). Like,
int max = Math.max(Math.max(x, y), z), min = Math.min(Math.min(x, y), z);
System.out.printf("%d%d%d%n", max, x + y + z - max - min, min);
Something like this would work
ArrayList<Integer> myList = new ArrayList<Integer>();
Scanner val = new Scanner(System.in);
int x = 0;
for (int i = 0; i < 3; i++) {
System.out.println("Enter a value");
x = val.nextInt();
myList.add(x);
}
myList.sort(null);
String answer = "";
for (int i = myList.size() - 1; i >= 0; i--) {
answer += myList.get(i).toString();
}
System.out.println(answer);
}
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.
In a program, a double is being converted to BigDecimal. This returns a very strange error message.
public static double riemannFuncForm(double s) {
double term = Math.pow(2, s)*Math.pow(Math.PI, s-1)*
(Math.sin((Math.PI*s)/2))*gamma(1-s);
if(s == 1.0 || (s <= -1 && s % 2 == 0) )
return 0;
else if (s >= 0 && s < 2)
return getSimpsonSum(s);
else if (s > -1 && s < 0)
return term*getSimpsonSum(1-s);
else
return term*standardZeta(1-s);
}
BigDecimal val = BigDecimal.valueOf(riemannFuncForm(s));
System.out.println("Value for the Zeta Function = "
+ val.toEngineeringString());
This returns
Exception in thread "main" java.lang.NumberFormatException
What is causing this error message? Does BigDecimal.valueOf(double) not work correctly since this is referenced through another method?
Full program
/**************************************************************************
**
** Euler-Riemann Zeta Function
**
**************************************************************************
** XXXXXXXXXX
** 06/20/2015
**
** This program computes the value for Zeta(s) using the standard form
** of Zeta(s), the Riemann functional equation, and the Cauchy-Schlomilch
** transformation. A recursive method named riemannFuncForm has been created
** to handle computations of Zeta(s) for s < 2. Simpson's method is
** used to approximate the definite integral calculated by the
** Cauchy-Schlomilch transformation.
**************************************************************************/
import java.util.Scanner;
import java.math.*;
public class ZetaMain {
// Main method
public static void main(String[] args) {
ZetaMain();
}
// Asks the user to input a value for s.
public static void ZetaMain() {
double s = 0;
double start, stop, totalTime;
Scanner scan = new Scanner(System.in);
System.out.print("Enter the value of s inside the Riemann Zeta " +
"Function: ");
try {
s = scan.nextDouble();
}
catch (Exception e) {
System.out.println("You must enter a positive integer greater " +
"than 1.");
}
start = System.currentTimeMillis();
if (s == 1)
System.out.println("The zeta function is undefined for Re(s) " +
"= 1.");
else if (s < 2) {
BigDecimal val = BigDecimal.valueOf(riemannFuncForm(s));
System.out.println("Value for the Zeta Function = "
+ val.toEngineeringString());
}
else
System.out.println("Value for the Zeta Function = "
+ BigDecimal.valueOf(getStandardSum(s)).toString());
stop = System.currentTimeMillis();
totalTime = (double) (stop-start) / 1000.0;
System.out.println("Total time taken is " + totalTime + " seconds.");
}
// Standard form of the Zeta function.
public static double standardZeta(double s) {
int n = 1;
double currentSum = 0;
double relativeError = 1;
double error = 0.000001;
double remainder;
while (relativeError > error) {
currentSum = Math.pow(n, -s) + currentSum;
remainder = 1 / ((s-1)* Math.pow(n, (s-1)));
relativeError = remainder / currentSum;
n++;
}
System.out.println("The number of terms summed was " + n + ".");
return currentSum;
}
// Returns the value calculated by the Standard form of the Zeta function.
public static double getStandardSum(double s){
return standardZeta(s);
}
// Approximation of the Gamma function through the Lanczos Approximation.
public static double gamma(double s){
double[] p = {0.99999999999980993, 676.5203681218851,
-1259.1392167224028, 771.32342877765313,
-176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6,
1.5056327351493116e-7};
int g = 7;
// Implements Euler's Reflection Formula.
if(s < 0.5) return Math.PI / (Math.sin(Math.PI * s)
*gamma(1-s));
s -= 1;
double a = p[0];
double t = s + g + 0.5;
for(int i = 1; i < p.length; i++){
a += p[i] / (s+i);
}
return Math.sqrt(2*Math.PI)*Math.pow(t, s+0.5)
*Math.exp(-t)*a;
}
/* Riemann's Functional Equation - Directly calculates the value of
Zeta(s) for s < 2.
1. The first if statement handles the case when s < 0 and s is a
multiple of 2k. These are trivial zeroes where Zeta(s) is 0.
2. The second if statement handles the values of 0 < s < 2. Simpson's
method is used to numerically compute an approximation of the
definite integral.
3. The third if statement handles the values of -1 < s < 0. Recursion
is used alongside an approximation through Simpson's method.
4. The last if statement handles the case for s <= -1 and is not a
trivial zero. Recursion is used directly against the standard form
of Zeta(s).
*/
public static double riemannFuncForm(double s) {
double term = Math.pow(2, s)*Math.pow(Math.PI, s-1)*
(Math.sin((Math.PI*s)/2))*gamma(1-s);
if(s == 1.0 || (s <= -1 && s % 2 == 0) )
return 0;
else if (s >= 0 && s < 2)
return getSimpsonSum(s);
else if (s > -1 && s < 0)
return term*getSimpsonSum(1-s);
else
return term*standardZeta(1-s);
}
// Returns the function referenced inside the right hand side of the
// Cauchy-Schlomilch transformation for Zeta(s).
public static double function(double x, double s) {
double sech = 1 / Math.cosh(x); // Hyperbolic cosecant
double squared = Math.pow(sech, 2);
return ((Math.pow(x, s)) * squared);
}
// Simpson's rule - Approximates the definite integral of f from a to b.
public static double SimpsonsRule(double a, double b, double s, int n) {
double simpson, dx, x, sum4x, sum2x;
dx = (b-a) / n;
sum4x = 0.0;
sum2x = 0.0;
// 4/3 terms
for (int i = 1; i < n; i += 2) {
x = a + i * dx;
sum4x += function(x,s);
}
// 2/3 terms
for (int i = 2; i < n-1; i += 2) {
x = a + i * dx;
sum2x += function(x,s);
}
// Compute the integral approximation.
simpson = function(a,s) + function(a,b);
simpson = (dx / 3)*(simpson + 4 * sum4x + 2 * sum2x);
return simpson;
}
// Handles the error for for f(x) = t^s * sech(t)^2. The integration is
// done from 0 to 100.
// Stop Simspson's Method when the relative error is less than 1 * 10^-6
public static double SimpsonError(double a, double b, double s, int n)
{
double futureVal;
double absError = 1.0;
double finalValueOfN;
double numberOfIterations = 0.0;
double currentVal = SimpsonsRule(a,b,s,n);
while (absError / currentVal > 0.000001) {
n = 2*n;
futureVal = SimpsonsRule(a,b,s,n);
absError = Math.abs(futureVal - currentVal) / 15;
currentVal = futureVal;
}
// Find the number of iterations. N starts at 8 and doubles
// every iteration.
finalValueOfN = n / 8;
while (finalValueOfN % 2 == 0) {
finalValueOfN = finalValueOfN / 2;
numberOfIterations++;
}
System.out.println("The number of iterations is "
+ numberOfIterations + ".");
return currentVal;
}
// Returns an approximate sum of Zeta(s) through Simpson's rule.
public static double getSimpsonSum(double s) {
double constant = Math.pow(2, (2*s)-1) / (((Math.pow(2, s)) -2)*
(gamma(1+s)));
System.out.println("Did Simpson's Method.");
return constant*SimpsonError(0, 100, s, 8);
}
}
Would I have to change all of my double calculations to BigDecimal calculations in order to fix this?
Nope. All you would need to do is to catch and handle the NumberFormatException appropriately. Or, test for NaN and Inf before attempting to convert the double.
In this case, you are only using BigDecimal for formatting in "engineering" syntax. So another alternative would be to do the formatting directly. (Though I haven't found a simple way to do that yet.)
This error occurs with you because BigDecimal.valueOf(value) does not accept "NaN" "Not a Number" as parameter and the following expression will return NaN
Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s)
this Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2)) will evaluate -0.0
and this function gamma(1-s) will evaluate "Infinity"
So -0.0 * Infinity equal NaN in java
please see this to know When can Java produce a NaN.
When can Java produce a NaN?
// write static methods here
public static double [] calcDarts(double [] trial, int numtrials)throws IOException
{
double x;
double y;
for(int n = 0; n < numtrials; n++)
{
x = Math.random();
y = Math.random();
double radius = (Math.pow(x, 2) + Math.pow(y,2));
if(radius <= 1)
trial = trial / numtrials * 4;
}
}
The error says the last line of code: trial = trial / numtrials * 4; "The operator / is undefined for the argument type(s) double[], int." How can I have it produce a double value for the variable trial?
You can't use a double array to calculate with an integer. Do it like this: You have to use the double values in the array:
for(int n = 0; n < numtrials; n++)
{
x = Math.random();
y = Math.random();
double radius = (Math.pow(x, 2) + Math.pow(y,2));
if(radius <= 1)
trial[n] = trial[n] / numtrials * 4;
}
But I think it is not good to calculate directly with the parameter. Create inside a Array to put the result and return it or something like that.
trial is an array of doubles, the operators / and *are obviously not defined for the use with an array. What you problably want to do is multiplying a single number form the array like this:
trial[n] = trial[n] / numtrials * 4;