This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 5 years ago.
Folks, hope you could point me, what I missing out. I am new to programming and now solving problems for Project Euler. One of the tasks is to calculate the sum of even numbers of Fibonacci sequence. I wrote code which passed 4 of 5 test. Here it is:
//N is input (N<=4*10^16), let's find n by Binet's formula
double a = log10(sqrt (5) * N);
double b = log10((1 + sqrt (5)) / 2);
int n = (int) (a / b);
//Using same formula, we find every Fibonacci number till n
for (int i = 1; i <= n; i++){
a = (1 + sqrt(5)) / 2;
long fiboNum = Math.round (Math.pow(a,i) / sqrt(5));
And here is my problem: when I run a test with big numbers, there is some rounding happening around F(71).
By my code, F(71) is 308 061 521 170 130, according to WolphramAlpha calculations 308 061 521 170 129.
Because of this, final sum is wrong.
Also, while testing I printed out all numbers and recognize, that even numbers repeat every 3. But even if I simplify it to the small loop of sum every third number, still problem exist.
If I do not use Math.round, I am getting the wrong sequence...
double has a limited precision. Try using BigDecimal which has precision only limited by the size of available memory.
Here is how you compute square root with BigDecimals: Square root of BigDecimal in Java
pow(): Java's BigDecimal.power(BigDecimal exponent): Is there a Java library that does it?
Rounding: Java BigDecimal: Round to the nearest whole value
Other operations like addition and division are built-in into BigDecimal as methods.
Related
This question already has answers here:
Large Numbers in Java
(6 answers)
Closed 5 years ago.
I've written a method that tests whether a number is prime or not. To maximise the range of numbers that the user can input, I wanted to use doubles. The issue is, after testing it on a very large prime, like 40 digits or so, my method returns false (I've already tested the logic with an int version, and it works just fine as far as I can tell).
Here is my code:
public static boolean isPrime(double number) {
double sqrt = Math.sqrt(number);
for(double i = 2; i<= sqrt; i++) {
if(number%i == 0) {
return false;
}
}
I know the reason it's not working at very high numbers is because of the accuracy error, but is there around this?
I know the reason it's not working at very high numbers is because of the accuracy error, but is there around this?
Yes. Use BigInteger.
Note that long would be better than double, since long can represent all integers up to 2^63 - 1 precisely. By contrast, with double you start losing precision at 2^53 + 1. However neither of these types are suitable for 40 (decimal) digit numbers.
BigInteger arithmetic is significantly slower, but the you will be able to go up to (at least) 2^Integer.MAX_VALUE ... provided that you have enough heap space.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
f(n) = f(n-1) + f(n-2) + f(n-1)*f(n-2);
1 <= n <= 10^9. Initial terms --> 1 <= f(0), f(1) <= 10^9.
Output the answer modulo 10^9 + 7.
The general term that I have found is,
f(n) = (((1 + f(1))^T(n)) * ((1 + f(0))^T(n-1))) - 1;
Here T(n) is the nth Fibonacci number.
I use matrix exponentiation and modular power to solve the problem, but it gives TLE.
As long as you haven't provided a sample of your code, I will give you a general idea.
Personally I wouldn't use recursion because n can be large thus leading to inefficient and long calculations filling stack and cause an overflow. So better inplement a cycle using array.
Next tip is to keep numbers relatively small, computing modulo on each step. (a+b+ab)%m is equal to (a%m + b%m + (a%m)*(b%m))%m (see wiki) so that we keep our numbers in range 0..10^9
Here is an example of solution:
const unsigned int mod = 1e9+7;
std::vector<unsigned int> vec(n+1); // prepare vector of needed size
// size is n+1 because we start from 0 and you need vec[n]
vec[0] = 1;
vec[1] = 1e9;
unsigned long long int r1, r2; // long long will prevent r1*r2 from overflowing
for (unsigned int i = 2; i <= n; ++i)
{
r1 = vec[i-1] % mod;
r2 = vec[i-2] % mod;
vec[i] = (r1 + r2 + r1*r2) % mod;
}
std::cout << vec[n];
You tagged your question with [c++] and [java]. Above code is in [c++] and I hope you would be able to port it if you need
k=1000000007 is prime. So a^b mod k is equivalent to a^(b mod (k-1)).
mod k, f(0)+1 is 2 and f(1)+1 is -6.
Raising things to powers can be efficiently done by repeated squaring and selecting squares to multiply together.
Calculating the nth Fibbonacci mod 1000000006 is tricky (for large n). I'm unaware of a simple closed form.
Aha! The Pisano period is the period over which the Fibbonnacci numbers mod some value repeat. k is decomposed into primes 2 * 500,000,003
Simply calculate the Pisano period of 2 and 500000003. Take the LCM of the pisano period of those two primes to get the pisano period of their product. We can use this to reduce the value n modulo this number before feeding it to Fibbonnacci.
This gives us a bounded Fibbonnacci calculation (hopefully tractible), to get us the Fibbonnacci result mod 1000000006, which we can then use the square technique (mod 1000000007) to raise 2 and -6 to that power, add them together and subtract 1.
Good luck calculating the Pisano period. If it is reasonable (and most look to be), you should be able to take a billion-digit n and solve in a fraction of a second.
Now, the Pisano period and closed forms of Fibbonnacci is based off some number theory and math. So instead we could try to directly generate a similar number theory/etc result for this recurrance relation rather than going through the identity you found. Arguably that wouod be harder, but might result in a cleaner answer.
This question already has answers here:
How to round a number to n decimal places in Java
(39 answers)
Closed 7 years ago.
I have to divide 495/116533, i tried using long and double; but it's returning 0.0;
Once if i able to capture that value (0.004247) then i can use round of methods;
Please help me how to capture complete value( which data type it supports?)
For 4 decimals do:
(double) (Math.round(value * 10000) / 10000)
The number of zeroes is how many decimals you want to round to.
Essentially what you need to do is to first multiply your number by a factor of X so that only the section you want to show is in front of the decimal place, then you can round it using the Math.round function. After that, just divide it back by X in order to put the decimal back in the right spot.
This question already has answers here:
Division of integers in Java [duplicate]
(7 answers)
Closed 8 years ago.
It's been a long day for me and I don't know if I can't do second grade math or if I'm doing something wrong in terms of how to do math in java. I'm not new to java, I started about a year and a half ago, but like I said, it's been a long day.
Here is my code:
System.out.println(5 / 150 * 100);
I expect to get something like "3.3333" or at least "3", but I get "0" instead. Why is that and how do I fix it?
Your second grade math is perfectly correct. However, 5 / 150 = 0.03 will become zero because its type is int. Then multiplying 0 with 100 won't change anything.
Use floats or doubles and you'll get the right result. Which of these two you use, depends on your needs. If you need a very precise value (a freaking lot of 3s behind the point) use double because it has - as its name tells you - two times the precision of a float.
All of your operand is int value and it will result in int value.
Try to change your operand to float value.
Try this:
System.out.println(5f / 150 * 100);
System.out.println(5 / 150f * 100);
This question already has answers here:
Why does division result in zero instead of a decimal?
(5 answers)
Closed 8 years ago.
I have hit a snag in my program when this calculates I get result of 0.0
y = 1/6*Math.pow(x,3)+1/2*Math.pow(x,2)-1/3*x;
I have tried writing the equation in chunks so I can add the results up after calculation but the result just keeps ending up being 0.0 and I don't know why. Is this a syntactical error or is there a rule that I'm missing about java?.
When you divide two integers Java truncates the result to an integer. If you want a fractional result you need to use floating point numbers. 1/2 is 0; 1.0/2.0 is 0.5.
y = 1.0/6.0*Math.pow(x,3) + 1.0/2.0*Math.pow(x,2) - 1.0/3.0*x;
y = 1/6*Math.pow(x,3)+1/2*Math.pow(x,2)-1/3*x;
Here you are doing division of two integers, which would result in 0. Make one/both of the values to decimal (1.0/6.0 etc) and then try this. It should give the correct result. The reason is that, 1/6 will be corrected to the closest integer value, which is 0.