This is my code,it has been one hour but it hasn't returned a value yet,is there anything wrong?
import java.math.BigInteger;
public class PROJECTV1 {
public static void main(String[] args) {
BigInteger bResult = bigFunctionExample_2();
System.out.println(" => result_got:" + bResult);
System.out.println(); //newline
}// end_main
public static BigInteger bigFunctionExample_2() {
BigInteger bSum = BigInteger.ZERO;
BigInteger bTmp;
String sSum;
// BigInteger bResult =0;
for (int i = 1; ; i++) {
bTmp = BigInteger.valueOf(i);
bTmp = bTmp.pow(2); // i^2
bSum = bSum.add(bTmp); // sum = i^2+ (i-1)^2 + ....
sSum = bSum.toString();
if (sSum.length() > 30) {
System.out.println("i=" + i + " bSum =" + bSum);
break;
}
}//end_for
return bSum; // result
}
// end_bigFunctionExample_2
}
For that loop to break, it must reach 10^30 ~= 2^100. Sum of the squares of the first n natural numbers is approximately equal to n^3. So your loop will break approximately when i becomes 10^10 ~= 2^33. I guess int i is 32-bit so you MIGHT be are overflowing that integer, I didn't do the exact math but it's very possible.
If you go for a 64-bit variable (long?), which has an upper limit of approximately 10^19, you might have a chance it will be OK.
Edit: Here's the exact math from WolframAlpha.
Related
I am doing an assignment where I must use nested loops in order to add up the squares and cubes of integers from 1 to N (N being whatever the user inputs). For example, if the user input the number 5, the program is supposed to do "1²+2²+3²+4²+5²" and output the sum of those numbers, as well "1³+2³+3³+4³+5³" and output the sum of those numbers.
However, I am having trouble figuring out how to code it in a way that I receive the proper output? This is what I wrote. Scanners were already added.
int limitNum = input.nextInt();
double squareNums:
double sumofSq = 0;
double cubedNums;
double sumofCubes = 0;
for(int s = 1; s <= limitNum; s++)
{
for(int c = 1; c <= limitNum; c++)
{
cubedNums = Math.pow(c, 3);
sumofCubes = sumofCubes + cubedNums;
}
squareNums= Math.pow(s, 2);
sumofSq = sumofSq + squareNums;
}
But currently, when I run this program, the sum of the squares output correctly, but the sum of the cubes is always some big number. For example if 5 is used, sumofSq would output 55.0, but sumofCubes would output 1125.0.
There is no point using a nested loop as this would result in complexity of O(n²). A single loop would be sufficient and be in complexity class O(n).
public class Application {
public static void main(String[] args) {
var squareSum = 0d;
var cubeSum = 0d;
var upperBound = 5;
for(var i = 1; i <= upperBound; i++){
squareSum += Math.pow(i, 2);
cubeSum += Math.pow(i, 3);
}
System.out.printf("""
Sum of first n squares: %s
Sum of first n cubes: %s
""", (int)squareSum, (int)cubeSum);
}
}
In fact there is no need to loop at all => constant computation time no matter the size of the input O(1). There is a well known formula which tells you the sum of the first n squares.
n(n+1)(2n+1)
------------
6
Please see this for a proof.
The same holds true for the first n cubes.
n²(n+1)²
--------
4
Please see this for a proof.
The following program will therefore return the same result.
public class Application {
public static void main(String[] args) {
var upperBound = 5;
System.out.printf("""
Sum of first n squares: %s
Sum of first n cubes: %s
""", sumOfFirstNSquares(upperBound), sumOfFirstNCubes(upperBound));
}
public static int sumOfFirstNSquares(int n){
return (n * (n+1) * (2 * n + 1)) / 6;
}
public static int sumOfFirstNCubes(int n){
return ((n * n) * (n+1) * (n+1)) / 4;
}
}
In fact there is no need to loop at all => constant computation time no matter the size of the input O(1). There is a well known formula which tells you the sum of the first n squares.
java
Fibonacci sequence is defined as a sequence of integers starting with 1 and 1, where each subsequent value is the sum of the preceding two I.e.
f(0) = 1
f(1) = 1
f(n) = f(n-1) + f(n-2) where n>=2
My goal is to calculate the sum of the first 100 even-values Fibonacci numbers.
So far I've found this code which works perfectly to calculate the sum of even numbers to 4million , however I'm unable to find edit the code so that it stops at the sum of the 100th value, rather than reaching 4million.
public class Improvement {
public static int Fibonacci(int j) {
/**
*
* Recursive took a long time so continued with iterative
*
* Complexity is n squared.. try to improve to just n
*
*/
int tmp;
int a = 2;
int b = 1;
int total = 0;
do {
if(isEven(a)) total +=a;
tmp = a + b;
b = a;
a = tmp;
} while (a < j);
return total;
}
private static boolean isEven(int a) {
return (a & 1) == 0;
}
public static void main(String[] args) {
// Notice there is no more loop here
System.out.println(Fibonacci(4_000_000));
}
}
Just to show the console from #mr1554 code answer, the first 100 even values are shown and then the sum of all is 4850741640 as can be seen below:
Any help is appreciated, thanks!
You need to use BigInteger because long easily overflows as Fibonacci's scales quite easily. BigInteger is also tricky to check whether is an odd or even number, but you can use BigInteger::testBit returning boolean as explained in this answer.
Here is some complete code:
BigInteger fibonacciSum(int count, boolean isOdd) {
int i = 0;
BigInteger sum = BigInteger.ZERO;
BigInteger current = BigInteger.ONE;
BigInteger next = BigInteger.ONE;
BigInteger temp;
while (i < count) {
temp = current;
current = current.add(next);
next = temp;
if ((current.testBit(0) && isOdd) || ((!current.testBit(0) && !isOdd))) {
sum = sum.add(current);
i++;
}
}
return sum;
}
Or you can have some fun with Stream API:
BigInteger fibonacciSum(int count, boolean isOdd) {
final BigInteger[] firstSecond = new BigInteger[] {BigInteger.ONE, BigInteger.ONE};
return Stream.iterate(
firstSecond,
num -> new BigInteger[] { num[1], num[0].add(num[1]) })
.filter(pair ->
(pair[1].testBit(0) && isOdd) ||
(!pair[1].testBit(0) && !isOdd))
.limit(count)
.map(pair -> pair[1])
.reduce(BigInteger.ZERO, BigInteger::add);
}
In any way, don't forget to test it out:
#Test
void test() {
assertThat(
fibonacciSum(100, false),
is(new BigInteger("290905784918002003245752779317049533129517076702883498623284700")));
}
You said.
My goal is to calculate the sum of the first 100 even-values Fibonacci numbers.
That number gets very large very quickly. You need to:
use BigInteger
use the mod function to determine if even
For this I could have started from (1,1) but it's only one term so ...
BigInteger m = BigInteger.ZERO;
BigInteger n = BigInteger.ONE;
BigInteger sumOfEven= BigInteger.ZERO;
int count = 0;
BigInteger t;
while( count < 100) {
t = n.add(m);
// check if even
if (t.mod(BigInteger.TWO).equals(BigInteger.ZERO)) {
sumOfEven = sumOfEven.add(t);
count++;
}
n = m;
m = t;
}
System.out.println(sumOfEven);
Prints
290905784918002003245752779317049533129517076702883498623284700
If, on the other hand, from your comment.
My aim is to calculate the sum of the first 100 even numbers
Then you can do that like so
sumFirstNeven = (((2N + 2)N)/2 = (N+1)N
so (101)100 = 10100 and the complexity is O(1)
as I figured, you want a program to sum 100 first even values of the Fibonacci series.
here is a sample code, when you run the program it will ask you to determine the number of the even values, you want 100 value e.g, type 100 in consul:
public static void main(String[] args) {
int firstNumber = 0;
int secondNumber = 2;
System.out.print("Enter the number of odd elements of the Fibonacci Series to sum : ");
Scanner scan = new Scanner(System.in);
int elementCount = scan.nextInt(); // number of even values you want
System.out.print(firstNumber + ", ");
System.out.print(secondNumber + ", ");
long sum = 2;
for (int i = 2; i < elementCount; i++) {
int nextNumber = firstNumber + secondNumber;
System.out.print(nextNumber + ", ");
sum += (nextNumber);
firstNumber = secondNumber;
secondNumber = nextNumber;
}
System.out.print("...");
System.out.println("\n" + "the sum of " + elementCount + " values of fibonacci series is: " + sum);
}
This code calculates the function f(x) = -1 + 2 + -3 + 4 + ... + (( - 1)^n)*n
But when the input(n) is too big, like 1000000000, java doesn't display an output.
What can I do to solve this problem?
import java.util.Scanner;
public class Calculating_function {
public static void main(String[] args) {
Scanner input_taker = new Scanner(System.in);
String n_string = input_taker.nextLine();
long n = Long.parseLong(n_string);
System.out.println(fonk(n));
}
public static long fonk(long n) {
long total = 0;
for(long i = 1; i <= n; i++) {
total += (long)Math.pow(-1, i) * i;
}
return total;
}
As the value of i increases, your exponent calculation Math.pow(-1, i) will take longer and longer to calculate.
As you're using Math.pow(-1, i) to simply swap the sign, you can optimize it as Math.pow(-1, i%2). Better yet, map the multiplier to the values 1 and -1 and use i%2 as your key.
Additionally, you are risking overflows as your total has an upper bound of 500,000,000,000,000,000 so use BigInteger instead to store the total.
I found this Fermat's algorithm for testing primes and I found out that it doesn't always return true for Carmichael numbers (such as 561). I tried to find the problem but I can't find anything wrong with the algorithm. What could be the problem?
import java.util.Scanner;
import java.util.Random;
import java.math.BigInteger;
public class FermatTest {
private final static Random rand = new Random();
private static BigInteger getRandomFermatBase(BigInteger n)
{
while (true)
{
final BigInteger a = new BigInteger (n.bitLength(), rand);
if (a.compareTo(BigInteger.ONE) == 1 && a.compareTo(n) < 0)
{
return a; // 1 <= a < n
}
}
}
public static String checkPrime(BigInteger n, int maxIterations)
{
if (n.equals(BigInteger.ONE))
return "is composite";
for (int i = 0; i < maxIterations; i++)
{
BigInteger a = getRandomFermatBase(n); //generate random a
a = a.modPow(n.subtract(BigInteger.ONE), n); //a^(p-1) mod p
if (!a.equals(BigInteger.ONE)) // not equals 1
return "is composite";
}
return "is probably prime";
}
public static void main(String[] args)
{
long start = System.nanoTime();
BigInteger n = new BigInteger("561");
System.out.println(n + " " + checkPrime(n , 20));
float time = System.nanoTime() - start;
System.out.println("Time: " + (long) time + " nanoseconds");
time = time / (1000000000);
System.out.println("Time: " + time + " seconds");
}
}
You identified the problem yourself. There are some numbers, the Carmichael numbers, that are improperly marked prime by the Fermat test for all possible bases. That's just a fact of number theory. You will need a different test to discriminate numbers as prime or composite.
This was part of my assignment and was asked to calculate factorial of 5 and 7.
I finished it as below:
import java.util.Scanner;
public class Factorial {
public static void main(String [] args)
{
System.out.println("Please enter a number: ");
Scanner input=new Scanner(System.in);
int number=input.nextInt();
int i,fact=1;
for(i=1;i<=number;i++){
fact=fact*i;
}
System.out.println("Factorial of " + number + " is: " + fact);
}
}
It worked for 5 and 7 (resulting 120 and 5040).
But my professor came over and test it with 20 and 987654321, result returns -2102132736 and 0.
Why is that?
P.S. I thought for the case of 987654321, the result would crush the application or return error since it would be huge.
This code can solve your problem . It is taken from here
class BigFactorial
{
static void factorial(int n)
{
int res[] = new int[300];
// Initialize result
res[0] = 1;
int res_size = 1;
// Apply simple factorial formula n! = 1 * 2 * 3 * 4...*n
for (int x=2; x<=n; x++)
res_size = multiply(x, res, res_size);
System.out.println("Factorial of given number is: ");
for (int i=res_size-1; i>=0; i--)
System.out.print(res[i]);
}
// This function multiplies x with the number represented by res[].
// res_size is size of res[] or number of digits in the number represented
// by res[]. This function uses simple school mathematics for multiplication.
// This function may value of res_size and returns the new value of res_size
static int multiply(int x, int res[], int res_size)
{
int carry = 0; // Initialize carry
// One by one multiply n with individual digits of res[]
for (int i=0; i<res_size; i++)
{
int prod = res[i] * x + carry;
res[i] = prod % 10; // Store last digit of 'prod' in res[]
carry = prod/10; // Put rest in carry
}
// Put carry in res and increase result size
while (carry!=0)
{
res[res_size] = carry%10;
carry = carry/10;
res_size++;
}
return res_size;
}
// Driver program
public static void main(String []args)
{
factorial(100);
}
}
Because 5040! is a very larger number (even long overflows). Use a BigInteger like
System.out.println("Please enter a number: ");
Scanner input = new Scanner(System.in);
int number = input.nextInt();
BigInteger fact = BigInteger.ONE;
for (int i = 2; i <= number; i++) { // <-- x * 1 = x
fact = fact.multiply(BigInteger.valueOf(i));
}
System.out.println("Factorial of " + number + " is: " + fact);
This is because of the fact that the container that you have taken for storing and printing your result does not have the capacity to hold such big integer (I mean factorial of 20). So, you need a bigger container. As others already suggested, you can use BIGINTEGER.