Java program factorials - java

Here's how it's written in the book:
"The value e^x can be approximated by the following sum:
1+x+x^2/2!+x^3/3!+...+x^n/n!
Write a program that takes a value x as input and outputs this sum for n taken to be each of the values 1 to 10, 50, and 100. Your program should repeat the calculation for new values of x until the user says she or he is through. The expression n! is called the factorial of n and is defined as
n! = 1*2*3*...*n
Use variables of type double to store the factorials (or arrange your calculation to avoid any direct calculation of factorials); otherwise, you are likely to produce integer overflow, that is, integers larger than Java allows."
I don't have any coding problems (not yet at least), my problem is I don't know what it's asking me to do. I get the factorial part (ex. 3i = 1*2*3) but I am just not sure what else it is asking. I have the user input a value for "x" but where does the "n" come from?
"The value e^x can be approximated by the following sum:
1+x+x^2/2!+x^3/3!+...+x^n/n!
" I don't know what this is saying or asking for.
I put together this for loop for the 1-10, 50, 100 part and I don't know if that even makes sense without understanding the rest, but here it is:
for (counter = 1 ; counter <= 100 ;counter++)
{
//System.out.print("Enter value for x: ");
//x = keyIn.nextDouble();
if (counter >= 1 && counter <= 10)
{
if (counter == 1)
System.out.println("Iterations 1-10: ");
System.out.println("test to see if 10 show up");
}
else if (counter == 50)
{
System.out.println("Iteration 50: ");
}
else if (counter == 100)
{
System.out.println("Iteration 100: ");
}
}
I haven't been in algebra in about two years so some of this stuff is throwing me off a bit. Please help with whatever you can, thanks.

It's saying that e^x can be approximated through a Taylor Series: Sum(i:0:n)(xi/fact(i))
So, we have:
double ex_taylor_series(double x, int n)
{
double value;
for(int i = 0; i < n; i++)
{
value += Math.pow(x, i)/(factorial(i));
}
return value;
}
private int factorial (int num)
{
int value = 1;
for(int i = num; i > 1; i--)
{
value *= i;
}
return value;
}
In your case, you would simply feed different values of n, 10, 50 and 100, to ex_taylor_series.

Related

Count Multiples

I have been assigned to write a java program for class that counts multiples. The program takes three integers as input: low, high, x. The program then outputs the number of multiples of x between low and high exclusively.
If the input is: 1, 10, 2
the output would be: 5
My teacher has the proclivity to assign problems we haven't covered in class and I am unsure where to begin. Im not asking for the full code, just how to set up the problem
I am unsure of how to follow my logic thru the program: what I have so far is this
import java.util.Scanner;
public class LabProgram {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
int low, high, x;
int count = 0;
low = scnr.nextInt();
high = scnr.nextInt();
x = scnr.nextInt();
for(int i = low; i <= high; i++){
if(i % x == 0){
count++;
}
if (i % x != 0){
//System.out.println(count);// someone suggested to move this
}
}
System.out.println(count);
}
}
~~~~~~
If I input 1, 10, 2
My output is 01234
Moved the print of count outside of the loop... man I am tired.
FINAL EDIT: This code works, it accomplishes the goal. Thank you to #charisma and everyone else that helped me understand what was going on here. I am new to java but determined to learn more! Thanks all!!!!!
You can input numbers using scanner class similar to the following code from w3schools:
import java.util.Scanner; // Import the Scanner class
class Main {
public static void main(String[] args) {
Scanner myObj = new Scanner(System.in); // Create a Scanner object
System.out.println("Enter username");
String userName = myObj.nextLine(); // Read user input
System.out.println("Username is: " + userName); // Output user input
}
}
low, high and x can be of data type int.
To check which numbers between low and high are multiples of x, you can use a for loop. You can declare a new variable count that can be incremented using count++ every time the for loop finds a multiple. The % operator could be useful to find multiples.
You can output using System.out.println(" " + );
Edit:
% operator requires 2 operands and gives the remainder. So if i % x == 0, it means i is a multiple of x, and we do count++.
The value of i will run through low to high.
for (i = low; i <= high; i++) {
if (i % x == 0) {
count++;
}
}
Once you get to the basic implementation (as explained by Charisma), you'll notice, that it can take a lot of time if the numbers are huge: you have high - low + 1 iterations of the loop. Therefore you can start optimizing, to get a result in constant time:
the first multiple is qLow * x, where qLow is the ceiling of the rational quotient ((double) low) / x,
the last multiple is qHigh * x, where qHigh is the floor of the rational quotient ((double) high) / x,
Java provides a Math.floor() and Math.ceil(), but you can get the same result using integer division and playing with the signs:
final int qLow = -(-low / x);
final int qHigh = high / x;
Now you just have to count the number of integers between qLow and qHigh inclusive.
return qHigh - qLow + 1;
Attention: if x < 0, then you need to use qLow - qHigh, so it is safer to use:
return x > 0 ? qHigh - qLow + 1 : qLow - qHigh + 1;
The case x == 0 should be dealt with at the beginning.
put count++; after the last print statement

Divide by Zero Exception with Typecaste (Java)

import java.util.Scanner;
public class SumDigits {
public static void main(String[] args)
{
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
// prompt the user to enter a value and store it as the integer called number
System.out.print("Enter an integer: ");
double number = Math.abs(input.nextDouble());
System.out.println("The sum of the digits is " + sumNumbers(number));
input.close();
}
public static int sumNumbers (double number)
{
int sum = 0;
for (int i = 10, digit = 0; (number * 10) /i !=0; i *= 10, digit = (int)((number % i) - digit)/(i / 10))
{
sum += digit;
}
return sum;
}
}
At runtime, I get the error message
Exception in thread "main" java.lang.ArithmeticException: / by zero
referring to line 25 (my for loop conditions).
The loop worked fine until I tried type casting digit's value to an int, and I'm not really certain why that would cause any part of the loop to divide something by zero. I've gone over all the possibilities regarding the conditions that use rational expressions and can't deduce a contingency wherein any denominator would be set to zero. I get this error regardless of what number is input. I would not have chosen to save number as a double at all if it were not for the fact that my professor provided a number whose value exceeds that which can be stored within an int in one of his test cases. The program ran fine prior to the type cast and provided the correct answer for all other test cases.
Here you are doing
(number * 10) /i !=0
where number is double.
Floating point numbers aren't recommended for comparisons because of the way they get stored (in mantissa and exponent form). So, if this condition returns true, consider yourself lucky.
Because of that your loop is kinda never-ending loop. The reason you are getting arithmetic exception though is that here you are multiplying i by 10 in this kinda infinite loop. "i" reaches "integer" limit of 32 bits and overflows and ultimately makes all those 32 bits as 0.
Effectively, i=0 and both of the following throw divide by zero exception
(number * 10) /i
and
(number % i) - digit)/(i / 10)
The root cause of the ArithmeticException is the incorrect loop condition. Adding System.out.println("i=" + i + " i*10=" + (i * 10)); in the loop produces output:
i=10 i*10=100
i=100 i*10=1000
i=1000 i*10=10000
i=10000 i*10=100000
i=100000 i*10=1000000
i=1000000 i*10=10000000
i=10000000 i*10=100000000
i=100000000 i*10=1000000000
i=1000000000 i*10=1410065408
i=1410065408 i*10=1215752192
i=1215752192 i*10=-727379968
i=-727379968 i*10=1316134912
i=1316134912 i*10=276447232
i=276447232 i*10=-1530494976
i=-1530494976 i*10=1874919424
i=1874919424 i*10=1569325056
i=1569325056 i*10=-1486618624
i=-1486618624 i*10=-1981284352
i=-1981284352 i*10=1661992960
i=1661992960 i*10=-559939584
i=-559939584 i*10=-1304428544
i=-1304428544 i*10=-159383552
i=-159383552 i*10=-1593835520
i=-1593835520 i*10=1241513984
i=1241513984 i*10=-469762048
i=-469762048 i*10=-402653184
i=-402653184 i*10=268435456
i=268435456 i*10=-1610612736
i=-1610612736 i*10=1073741824
i=1073741824 i*10=-2147483648
i=-2147483648 i*10=0
First time control enters into loop the value of digit would be zero and not the last digit of entered number as you would have expected. Also you need to fix your loop termination condition as that is wrong. For example if number is 123 then at last expected iteration 1230/1000 = 1 and not 0 and loop does not end and rather leads to overflow. You can use the following:
public static int sumNumbers (double number)
{
int sum = 0;
for (int i = 10, digit = (int)(number % i); digit != 0; i *= 10, digit = (int)((number % i) - digit)/(i / 10))
{
sum += digit;
}
return sum;
}
This should work but I again recommend you to improve this code as this is not the ideal way.
Testing:
Enter an integer: 3456
The sum of the digits is 18

sum(1/prime[i]^2) >= 1?

While trying to devise an algorithm, I stumbled upon this question. It's not homework.
Let P_i = an array of the first i primes. Now I need the smallest i such that
Sum<n=0..i> 1 / (P_i[n]*P_i[n]) >= 1.
(if such i exists).
An approximation for the i'th prime is i*log(i). So I tried this in Java:
public static viod main(String args[]) {
double sum = 0.0;
long i = 2;
while(sum<1.0) {
sum += 1.0 / (i*Math.log(i)*i*Math.log(i));
i++;
}
System.out.println(i+": "+sum);
}
However the above doesn't finish because it converges to 0.7. However 1/100000000^2 rounds to 0.0 in Java, so that's why it doesn't work. For the same reason it doesn't even work if you replace the 6th line with
sum += 1.0 / (i*i)
while that should reach 1 if I'm not mistaken, because the sum should incease faster than 1/2^i and the latter converges to 1. In other words, this shows that Java rounding causes the sum to not reach 1. I think that the minimum i of my problem should exist.
On the maths side of this question, not the java side:
If I understand the problem, there is no solution (no value of i).
For any finite set P_i of primes {p_1, p_2,...p_i} let N_i be the set of all integers up to p_i, {1,2,3,...,p_i}. The sum 1/p^2 (for all p_n in P_i) will be less than the sum of all 1/x^2 for x in N_i.
The sum of 1/x^2 tends to ~1.65 but since 1 will never be in the set of primes, the sum is limited by ~0.65
You cannot use double for this, because it is not uniform. You should use fractions. I found this class https://github.com/kiprobinson/BigFraction
Then I tried to find whats happening :
public static void main(String args[]) {
BigFraction fraction = BigFraction.valueOf(1, 4);
int n = 10000000, status = 1, num = 3;
double limit = 0.4;
for (int count = 2; count <= n;) {
for (int j = 2; j <= Math.sqrt(num); j++) {
if (num % j == 0) {
status = 0;
break;
}
}
if (status != 0) {
fraction = fraction.add(BigFraction.valueOf(1,BigInteger.valueOf(num).multiply(BigInteger.valueOf(num))));
if (fraction.doubleValue() >= limit){
System.out.println("reached " + limit + " with " + count + " firsts prime numbers");
limit += 0.01;
}
count++;
}
status = 1;
num++;
}
}
This is having this output :
reached 0.4 with 3 firsts prime numbers
reached 0.41000000000000003 with 4 firsts prime numbers
reached 0.42000000000000004 with 5 firsts prime numbers
reached 0.43000000000000005 with 6 firsts prime numbers
reached 0.44000000000000006 with 8 firsts prime numbers
reached 0.45000000000000007 with 22 firsts prime numbers
And nothing more in a minute. I debug it and found that it grows extremely slower and slower, I do not think, it can reach 1 even in infinity :) (but dont know how to prove it).
I guess you might loose the precision you need when you use default Math.log multiplied by float i. I think this can be handled by using an appropriate RoundingMode. Please see setRoundingMode

Simple program using loops (Beginning Java)

I have to write a program using loops that calculates the sum of all odd numbers between a and b (inclusive), where a and b are inputs.
I made this (below) and it works fine, but I noticed one problem with it: when i enter a larger number followed by a smaller number for the inputs, it returns 0, but when i enter the smaller number first it works perfectly. Any quick fixes for this? :)
import java.util.Scanner;
public class ComputeSumAAndB
{
public static void main (String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Please enter 2 integers: "); //prompts user for ints
int a = in.nextInt();
int b = in.nextInt();
int sum = 0;
for (int j = a; j <= b; j++)
{
if (j % 2 == 1)
sum += j;
}
System.out.println("The sum of all odd numbers (inclusive) between " + a + " and "+ b + " is " + sum);
}
}
int temp;
if(a > b) {
temp = a;
a = b;
b = temp;
}
Put this right before your for loop starts.
The if checks whether a (the first number entered) is larger than b. If it is, it swaps a and b. Now your for loop will always start with the smallest number and iterate up to the larger number (because after this if, a will always be the smaller number).
Using this method has the added side effect of making your output make sense. Your output will now always say: "between [smaller number] and [larger number]".
rolfl's answer is more elegant and works perfectly fine, but when the user enters the larger number first, your output may look kind of weird: "between [larger number] and [smaller number]", etc.
You can get the smaller and larger inputs by using the Math.min() and Math.max functions....
for (int j = Math.min(a,b); j <= Math.max(a,b); j++) {
if (j % 2 == 1) {
sum += j;
}
}
It's not working because A is larger than B in the for loop, you have it iterate while A is less than or equal to B.
You could do what nhgrif says but it's changing your data.. But he is correct.
That's because you are first expecting for the a input (inferior limit) and then the b (superior). When your program reaches the for, j = a so the condition a <= b is False, if the first input is larger. In other words it never enters the for loop.
Actually you should do the following 2 things:
1 It is just just like rolfl mentioned above. You need to put the min and max in the right place in loop.
for (int j = Math.min(a,b); j <= Math.max(a,b); j++)
{
if (j % 2 == 1) {
sum += j;
}
}
2 Use if (j % 2 == 1) it is not enough to check whether the num is odd.
e.g.
a = -5, b =0;
What will be the result?
int sum = 0;
for(int j=-5;j<0;j++)
{
if(j%2 == 1)
{
sum+=j;
}
}
The value for sum will be 0.
We need to change the condition to if(!(j%2 == 0)) Then you will get the expected result.
That's because you are first expecting for the a input (inferior limit) and then the b (superior). When your program reaches the for, j = a so the condition a <= b is False, if the first input is larger. In other words it never enters the for loop.

Java simple while loop confusion

I am having trouble with this simple loop for a uni lab. It wont stop looping until I put in a number over a thousand. I can't see where I have gone wrong on such a simple loop.
I have meant to have written a simple method that will loop through adding numbers until the number is greater than 100 and then once it has reached 100 or greater it will output the total.
public void adder2(){
int sum = 0;
int number = 0;
while(number < 100){
sum = sum + number;
number = getNumber();
}
System.out.println("The result is " + sum);
}
Try this:
while (sum < 100 && number < 100) { ...code as above... }

Categories