Integer precision [duplicate] - fortran

This question already has an answer here:
Fibonacci numbers becoming negative after a certain term
(1 answer)
Closed 5 years ago.
I was solving Project Euler problems using Fortran; the problem is to create a Fibonacci sequence and find the sum of all even numbers that come under 4 million. Here's what I wrote
implicit none
integer*4::a(1:4000000),sum
integer*4::i,maxc
maxc = 3999999
a(1) = 1
a(2) = 2
do i = 3,maxc,1
a(i) = a(i-1) + a(i-2)
end do
sum = 0
do i = 1,maxc
if (mod(a(i),2)==0) then
sum = sum + a(i)
end if
end do
print*,sum
end
The output is -1833689714
Any idea what went wrong?

Due to the size of the integer kind you chose, there is a limit to the numbers you can represent.
In your code it is 2147483647 (with gfortran, obtained by print *,huge(sum)).
It can be shown that this limit is exceeded for i=59 in your implementation.
Then, you get an integer overflow, and the value becomes negative.
Simply using a floating point representation for the sum, i.e.
real :: sum
Does the trick.

Related

How I can solve C++ output negative numbers when using modulo? [duplicate]

This question already has answers here:
Fastest way to get a positive modulo in C/C++
(9 answers)
How to code a modulo (%) operator in C/C++/Obj-C that handles negative numbers
(16 answers)
Closed 2 years ago.
In a code written by me, I have used both below functions to calculate mod of displayed negative number.
fmod(-10,11)
(-10, 11)
Though the correct answer is 1. It always displays the answer -10 in c++. How I can solve it?
From cppreference.com:
double fmod (double numer, double denom);
The floating-point remainder of the division operation x/y calculated by this function is exactly the value x - n*y, where n is x/y with its fractional part truncated.
The returned value has the same sign as x and is less than y in magnitude.
In your case it is -10 - (-10)/11 * 11 = -10 - 0 * 11 = -10, which is correct for that implementation of fmod. If you need another answer, you should implement your own version, as modulo is defined in different ways for negative numbers.

Why does "double i = 1/12;" yields to i = 0? [duplicate]

This question already has answers here:
Why does dividing two int not yield the right value when assigned to double?
(10 answers)
Closed 5 years ago.
I think the title says everything. I want to define a variable i as the fraction 1/12. However, i is 0.
double i = 1/12;
std::cout << i; // Output: 0
Or, more specific, I want to calculate a power of something:
im_ = std::pow((1 + i), (1/12)) - 1;
However, the compile evaluates (1/12) as 0 and thus the result is wrong.
Simple because 1/12 is evaluated as integer math, not floating point math.
1/12 becomes 0 because integer math does not take into account the decimal fractions.
To get the expected result you will need to write down the numbers as a floating point literal, like this: 1.0/12.0.
More details can be found here: Why can't I return a double from two ints being divided

Fortran calculate sum of floating numbers not getting exact precision [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 7 years ago.
I am new to Fortran90 , I have write a simple program to add two floating point numbers as follows:
program Numbers_sum
implicit none
REAL :: sum
sum = 1.6+2
print*,"Sum =", sum
end
I am getting the answer as Sum = 3.5999999
Why it is not getting 3.6. How Can I make this program to get the exact answer?? Any help will be appreciated.
There is no way to write 3.6 in base 2 with finite digits. It's 2 + 1 + 1/2 + 1/16 + ...
You can, however, hide the rounding error by selecting proper formatting:
write(*, '(F11.6)') sum
If you want to calculate in higher precision, you could use this:
REAL(KIND=8) :: var
Or, if you want to be really proper:
program numbers_sum
implicit none
integer, parameter :: dp = selected_real_kind(P=12)
real(kind=dp) :: sum1
sum1 = 1.6_dp + 2
print *, "Sum = ", sum1
end
But even this won't eliminate the rounding completely.
Cheers

Digit wise modulo for calculating power function for very very large positive integers

Hi I am writing a code to calculate P^Q where
P, Q are positive integers which can have number of digits upto 100000
I want the result as
result = (P^Q)modulo(10^9+7)
Example:
P = 34534985349875439875439875349875
Q = 93475349759384754395743975349573495
Answer = 735851262
I tried using the trick:
(P^Q)modulo(10^9+7) = (P*P*...(Q times))modulo(10^9+7)
(P*P*...(Q times))modulo(10^9+7) = ((Pmodulo(10^9+7))*(Pmodulo(10^9+7))...(Q times))modulo(10^9+7)
Since both P and Q are very large, I should store them in an array and do modulo digit by digit.
Is there any efficient way of doing this or some number theory algorithm which I am missing?
Thanks in advance
Here is a rather efficient way:
1)Compute p1 = P modulo 10^9 + 7
2)Compute q1 = Q modulo 10^9 + 6
3)Then P^Q modulo 10^9 + 7 is equal to p1^q1 modulo 10^9 + 7. This equality is true because of Fermat's little theorem. Note that p1 and q1 are small enough to fit in 32-bit integer, so you can implement binary exponention with standard integer type(for intermidiate computations, 64-bit integer type is sufficient because initial values fit in 32-bits).

to find power of a decimal number with exponent as floating point number without using math library [duplicate]

This question already has answers here:
How can I write a power function myself?
(14 answers)
Closed 9 years ago.
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
double x,y,z;
cin>>x>>y;
z=exp(y*log(x));
cout<<z;
system("pause");
return 0;
}
this is code to find power of a numbers whose exponent is floating point number i.e 2.3^2.3 if we do using logs and antilogs we can get the answer easily but my interview question was to find power with out using any math library in c++. i googled it and did not able to understand some of the refere nces from google.
You can always implement exp() and log() yourself.
And it's easier to actually implement 2x and log2x for the purpose and use in the same way as exp() and log().
2x = 2integer_part(x)+fractional_part(x) = 2integer_part(x) * 2fractional_part(x)
2fractional_part(x) can be calculated for -1 <= x <= +1 using Taylor series expansion.
And then multiplying by 2integer_part(x) amounts to adjusting the exponent part of the floating point number by integer_part(x) or you can indeed raise 2 to the integer power of integer_part(x) and multiply by that.
Similarly, log2x = log2(x * 2N) - N
where N (an integer, a power of 2) is chosen such that 0.5 <= x * 2N <= 1 (or, alternatively, between 1 and 2).
After choosing N, again, we can use Taylor series expansion to calculate log2(x * 2N).
And that's all, just a little bit of math.
EDIT: It's also possible to use approximating polynomials instead of Taylor series, they are more efficient. Thanks Eric Postpischil for reminding. But you'd probably need a math reference to find or construct those.
You could use Taylor series expansions for ln(x) and e^x:
ln(x) = 2 * sum[ ((x-1)/(x+1))^(2n-1) / (2n-1), n=1..inf ]
= 2 [ (x-1)/(x+1) + (1/3)( (x-1)/(x+1) )^3 + (1/5)( (x-1)/(x+1) )^5 + (1/7) ( (x-1)/(x+1) )^7 + ... ]
e^x = sum( x^n / n!, n = 0 .. inf )
= 1/1 + x/1 + x^2 / 2 + x^3 / 6 + ...
Where you could implement the integral powers as a for-loop and continue the expansion for the desired approximation. Then plug in your values, and badda-bing, badda-boom. Note the convergence regions for the above are for x > 0 for ln(x) and for all values for e^x.