hey guys I am trying to calculate pi using this formula:
pi = 4 ยท [ 1 โ 1/3 + 1/5 โ 1/7 + 1/9 ... + (โ1)^n/(2n + 1) ]
yet i always get a zero for my output pi value and I am really confused as to where I had gone wrong. Here is my code:
#include <cmath>
#include <iostream>
using namespace std;
int main()
{
int n;
double b = 0;
char c = 'Y';
int s = 1;
while (c == 'Y') {
cout << "Enter the value of the parameter 'n' in the Leibniz formula (or -1 to quit):" << endl;
cin >> n;
if (n != -1) {
c = 'Y';
for (int a = 1; a <= n; a++) {
s = -s;
b += 4 * (s/ (2 * a + 1));
}
cout << "The approximate value of pi using 1 term is:" << b << endl;
}
else {
c = 'N';
}
}
return 0;
}
In both C and C++, mathematical operations on integers result in an integer even if the result would be fractional in conventional mathematics. Change your int to a float or double and I suspect that it will work better.
The result is truncated to the integer value and has an integer type.
So for example: 2 / 4 results in 0 and 5 / 2 would result in 2.
NOTE if you perform an operation between a floating point value and an integer value, the result is a floating point value. So:
2.0 / 4 == 0.5
Your code seems to be complicated and int type is used in places where floating operations are expected.
Consider the following simplified example:
#include <cmath>
#include <iostream>
using namespace std;
int main()
{
int n = 0;
double b = 0;
double s = 1; // Tytpe is changed
while (n != -1) { // there is no need for char c
cout << "Enter the value of the parameter 'n' in the Leibniz formula (or -1 to quit):" << endl;
cin >> n;
b = 0; // init b before starting the loop
s = 1; // the same for s (it can be -1 from the next user input)
// there is no need for if (n != -1) because for has condition
for (int a = 1; a <= n; a++) {
s = -s;
b += 4 * (s / (2.0 * a + 1));
}
cout << "The approximate value of pi using 1 term is:" << b << endl;
}
return 0;
}
IMPORTANT UPDATE:
To make your calculation correct (in terms of Leibniz's formula) I suggest the following changes in the for loop:
for (int a = 0; a <= n; a+=2) { // start from 0 with step 2
b += 4.0 * (s / (a + 1.0));
s = -s; // change the sign for next calculation
}
and further, consider some kind of optimization
b = 0; // do not forget about reseting b to 0 before making sum
s = 1; // set 1 in the sign
for (int a = 0; a <= n; a+=2) { // start from 0 with step 2
b += s / (a + 1.0); // no multiplication on each iteration
s = -s; // because s was initialized with 1
}
b *= 4.0; // multiply once for the whole sum
UPDATE 2
For case if precision is really important for output, final snippet can be like:
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int n = 0;
double b = 0;
double s = 1;
int prec = 0;
cout << "What precision should be used for output? (Value from 1 to 10): ";
while (prec< 1 || prec > 10)
{
cin >> prec;
}
while (true) {
cout << "Enter the value of the parameter 'n' in the Leibniz formula (or -1 to quit):" << endl;
cin >> n;
if (n == -1)
{
break; // go out the loop if user enter -1 (want to exit)
}
else if (n <= 0)
{
cout << "'n' have to be 1 or greater" << endl;
continue; // go to the next iteration to ask new 'n'
}
s = 1;
b = 1.0; // we can start from 1 (no need to claculate the first term) and make loop from 2
for (int a = 2; a < n*2; a+=2) { // start from 2 with step 2 (so n should be doubled)
s = -s; // change the sign for this iteration, because now loop started from a = 2
b += s / (a + 1.0);
}
b *= 4.0;
cout << "The approximate value of pi using 1 term is: " << setprecision(prec+1) << b << " (PI = " << M_PI << ")" << endl;
}
return 0;
}
Note:
In this version b initialized with 1.0 because the first item in the Leibniz series is always 1 (we can skip calculation, but we should change the logic for sign changes - make s = -1; or move s = -s; before summation - I choose the 2nd option).
Also I'am not sure what is "parameter 'n' in the Leibniz formula", so pay attention to condition of for loop - now (with a < n*2) it is correct for case if n is number of items in the Leibniz series to be calculated.
Along with doing integer math, you have a few other minor problems.
First, the formula is [1 - ...], not [0 - ...], so you need to initialize b to 1.0, not 0.
Second, it's supposed to be 4 * [...], but you're multiplying by 4 on every iteration of the loop, so you're getting `[0 - b1 * 4 + b2 * 4 -b3 * 4 ....].
You can distribute the multiplication if you want to, but if you do you'll need to distribute it correctly (e.g., the starting value of 1.0 would also need to be multiplied by 4).
Also note that you're not re-initializing correctly, so the second (and subsequent) times you attempt to re-compute the value, you'll get completely incorrect answers (until you fix more stuff).
You've been burned by integer division.
b += 4 * (s/ (2 * a + 1));
a is an int so the division result is an int.
A cast to double will fix it:
b += 4 * (s/ (2 * double(a) + 1));
Related
So I was inspired by a recent Youtube video from the Numberphile Channel. This one to be exact. Cut to around the 5 minute mark for the exact question or example that I am referring to.
TLDR; A number is created with all the digits corresponding to 1 to N. Example: 1 to 10 is the number 12,345,678,910. Find out if this number is prime. According to the video, N has been checked up to 1,000,000.
From the code below, I have taken the liberty of starting this process at 1,000,000 and only going to 10,000,000. I'm hoping to increase this to a larger number later.
So my question or the assistance that I need is optimization for this problem. I'm sure each number will still take very long to check but even a minimal percentage of optimization would go a long way.
Edit 1: Optimize which division numbers are used. Ideally this divisionNumber would only be prime numbers.
Here is the code:
#include <iostream>
#include <chrono>
#include <ctime>
namespace
{
int myPow(int x, int p)
{
if (p == 0) return 1;
if (p == 1) return x;
if (p == 2) return x * x;
int tmp = myPow(x, p / 2);
if (p % 2 == 0) return tmp * tmp;
else return x * tmp * tmp;
}
int getNumDigits(unsigned int num)
{
int count = 0;
while (num != 0)
{
num /= 10;
++count;
}
return count;
}
unsigned int getDigit(unsigned int num, int position)
{
int digit = num % myPow(10, getNumDigits(num) - (position - 1));
return digit / myPow(10, getNumDigits(num) - position);
}
unsigned int getTotalDigits(int num)
{
unsigned int total = 0;
for (int i = 1; i <= num; i++)
total += getNumDigits(i);
return total;
}
// Returns the 'index'th digit of number created from 1 to num
int getIndexDigit(int num, int index)
{
if (index <= 9)
return index;
for (int i = 10; i <= num; i++)
{
if (getTotalDigits(i) >= index)
return getDigit(i, getNumDigits(i) - (getTotalDigits(i) - index));
}
}
// Can this be optimized?
int floorSqrt(int x)
{
if (x == 0 || x == 1)
return x;
int i = 1, result = 1;
while (result <= x)
{
i++;
result = i * i;
}
return i - 1;
}
void PrintTime(double num, int i)
{
constexpr double SECONDS_IN_HOUR = 3600;
constexpr double SECONDS_IN_MINUTE = 60;
double totalSeconds = num;
int hours = totalSeconds / SECONDS_IN_HOUR;
int minutes = (totalSeconds - (hours * SECONDS_IN_HOUR)) / SECONDS_IN_MINUTE;
int seconds = totalSeconds - (hours * SECONDS_IN_HOUR) - (minutes * SECONDS_IN_MINUTE);
std::cout << "Elapsed time for " << i << ": " << hours << "h, " << minutes << "m, " << seconds << "s\n";
}
}
int main()
{
constexpr unsigned int MAX_NUM_CHECK = 10000000;
for (int i = 1000000; i <= MAX_NUM_CHECK; i++)
{
auto start = std::chrono::system_clock::now();
int digitIndex = 1;
// Simplifying this to move to the next i in the loop early:
// if i % 2 then the last digit is a 0, 2, 4, 6, or 8 and is therefore divisible by 2
// if i % 5 then the last digit is 0 or 5 and is therefore divisible by 5
if (i % 2 == 0 || i % 5 == 0)
{
std::cout << i << " not prime" << '\n';
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
PrintTime(elapsed_seconds.count(), i);
continue;
}
bool isPrime = true;
int divisionNumber = 3;
int floorNum = floorSqrt(i);
while (divisionNumber <= floorNum && isPrime)
{
if (divisionNumber % 5 == 0)
{
divisionNumber += 2;
continue;
}
int number = 0;
int totalDigits = getTotalDigits(i);
// This section does the division necessary to iterate through each digit of the 1 to N number
// Example: Think of dividing 124 into 123456 on paper and how you would iterate through that process
while (digitIndex <= totalDigits)
{
number *= 10;
number += getIndexDigit(i, digitIndex);
number %= divisionNumber;
digitIndex++;
}
if (number == 0)
{
isPrime = false;
break;
}
divisionNumber += 2;
}
if (isPrime)
std::cout << "N = " << i << " is prime." << '\n';
else
std::cout << i << " not prime" << '\n';
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
PrintTime(elapsed_seconds.count(), i);
}
}
Its nice to see you are working on the same question I pondered few months ago.
Please refer to question posted in Math Stackexchange for better resources.
TL-DR,
The number you are looking for is called SmarandachePrime.
As per your code, it seems you are dividing with every number that is not a multiple of 2,5. To optimize you can actually check for n = 6k+1 ( ๐ โ โ ).
unfortunately, it is still not a better approach with respect to the number you are dealing with.
The better approach is to use primality test screening to find probable prime numbers in the sequence and then check whether they are prime or not. These tests take a less time ~(O(k log3n)) to check whether a number is prime or not, using mathematical fundamentals, compared to division.
there are several libraries that provide functions for primality check.
for python, you can use gmpy2 library, which uses Miller-Rabin Primality test to find probable primes.
I recommend you to further read about different Primality tests here.
I believe you are missing one very important check, and it's the division by 3:
A number can be divided by 3 is the sum of the numbers can be divided by 3, and your number consists of all numbers from 1 to N.
The sum of all numbers from 1 to N equals:
N * (N+1) / 2
This means that, if N or N+1 can be divided by 3, then your number cannot be prime.
So before you do anything, check MOD(N,3) and MOD(N+1,3). If either one of them equals zero, you can't have a prime number.
I want the result to be the returned value from the mystery function,but the result is always 0 .but I want the program to return a value that's collected from the mystery function
#include <iostream>
using namespace std;
int Mystery(int n)
{
// int k;
if (n <= 1)
{
return 0;
}
else
{
int k = n;
for (int i = 1; i <= n; i++)
{
k = k + 5;
}
cout << ((k * (n / 2)) + (8 * (n / 4)));
cout << "\n ";
return ((k * Mystery(n / 2)) + (8 * Mystery(n / 4)));
}
}
int main(void)
{
int i, n;
cout << "Enter n:"; //array size
cin >> n;
int result = Mystery(n);
cout << "The result is " << result;
return 0;
}
Let's desk check what happens when you call Mystery(2). The final return value is:
((k* Mystery(n/2)) + (8* Mystery(n/4)))
We know that n == 2 so let's substitute that:
((k* Mystery(1)) + (8* Mystery(0 /* by integer division of 2/4 */)))
This will call the function recursively twice with the respective arguments 1 and 0. But we know that the terminating case n <= 1 returns 0, so we can substitute that:
((k* 0) + (8* 0))
Anything multiplied by zero is zero, so this reduces to 0 + 0 which is also zero. It doesn't even matter what k is.
Quite simply, the terminating case for this recursion mandates that the result is always zero.
In the terminating case the return value is zero.
In the recursive case, the recursive call result is multiplied with another value to produce the return value.
Therefore, the result is always going to be zero for any n.
I'm not sure exactly how this function is supposed to work as you have not explained that, but changing the terminating case to return 1; may solve the problem.
I don't expect which result you want, but I think you can get write result when you correct conditions like
if (n == 0)
return 0;
if (n == 1)
return 1;
I hope it returns the right result.
This is a simple C++ program which computes f(x) using a formula for a fixed number of values between 2 given numbers.
There seems to be some problem when k = 0 in the for loop. It is returning a garbage value.
Can anyone tell me why?
Any help is highly appreciated. Thanks in advance.
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
int main ()
{
int const POINTS = 21;
double const PI = 3.1416;
double min, max, increment, dataPoints[21];
cout << "Enter max value: ";
cin >> max;
cout << "Enter min value: ";
cin >> min;
increment = (max - min) / (POINTS - 1);
cout << setw (20) << "X-Value" << "|";
cout << setw (20) << "Y-Value" << endl;
double k;
int l;
for (k = min, l = 0; l < POINTS, k <= max; l++, k += increment)
{
dataPoints[l] = (PI / 16) * sin (6.036 * k) + (1 / 64) * PI * cos (24.44 * k);
cout << setw (20) << k << setw (20) << dataPoints[l] << endl;
}
}
Output:
Enter max value: 4
Enter min value: -4
X-Value| Y-Value
-4 0.164018
-3.6 -0.0507715
-3.2 -0.0881608
-2.8 0.182492
-2.4 -0.184497
-2 0.0931637
-1.6 0.0453027
-1.2 -0.16085
-0.8 0.195021
-0.4 -0.130529
-5.55112e-016 -6.57901e-016
0.4 0.130529
0.8 -0.195021
1.2 0.16085
1.6 -0.0453027
2 -0.0931637
2.4 0.184497
2.8 -0.182492
3.2 0.0881608
3.6 0.0507715
4 -0.164018
Process returned 0 (0x0) execution time : 3.634 s
Press any key to continue.
One problem problem lies in the code (1 / 64) ... because you have put this expression in brackets. It is, thus, integer division and, as such, will always have the value of zero.
Try this, instead:
dataPoints[l] = (PI / 16) * sin (6.036 * k) + (1.0 / 64) * PI * cos (24.44 * k);
There is also a problem in the way you have expressed the 'test' condition in your for loop - the comma operator here will, effectively, ignore the first part of the expression:
for (k = min, l = 0; l < POINTS, k <= max; l++, k += increment)
For safety, when you want both conditions to be tested, use the && operator:
for (k = min, l = 0; l < POINTS && k <= max; l++, k += increment) {
Lastly, your actual question:
There seems to be some problem when k = 0 in the for loop. It is
returning a garbage value.
No, it's not! The floating-point operations you perform on the k variable (i.e. k += increment, on each loop) are not precise: what you think will be 0.4 + (-0.4) will actually be 'nearly' '0.4' - 'nearly' '0.4'; as such, the value you get (my system gives -5.55112e-16) is a 'reasonable approximation' to zero, given the ranges of the numbers that you've used (and the accumulated 'errors' in the previous loops).
Feel free to ask for further clarification and/or explanation.
Because of rounding error when you increment by 0.2, your k value never gets to be exactly zero -- its off by a little bit. See What every computer scientist should know about floating point
Attempting to use this for loop to take an input for how many times the loop should run. And every other time the loop runs it should subtract or add to the sum, the denominator will change by +2 every completed loop. Cannot for the life of me figure out why it does not work. The answer I get once the input is larger than 10 is negative when it should be oscillating over pi.
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
enter code here
int main()
{
int input = -100;
double sumTotal = 4, denominator = 3;
while (input < 0)
{
cout << "Enter Max value of k in truncated series (non-negative): " << endl;
cin >> input;
}
if (input == 0)
{
sum = 4.0 / 1.0;
}
for (int i = 2; i < input+2; i++)
{
if (i%2==0)
{
sumTotal -= static_cast<double>(4.0) / denominator;
}
else
{
sumTotal += static_cast<double>(4.0) / denominator;
}
denominator + static_cast<double>(2);
}
cout << sumTotal << endl;
return 0;
}
First things first: the static_casts you are doing are unnecessary. In C++, literals of the form 1.0 are considered doubles by default. Even if you used the float suffix, i.e. 1.0f, the compiler will still do the right thing.
Second, while I'm not familiar with the algorithm you are implementing, I would bet the issue is here: denominator + static_cast<double>(2);. This statement has no effect on the value of denominator.
You probably need to do this:
denominator = denominator + 2;
Or,
denominator += 2;
The intended effect is to modify the value of denominator for the next iteration of the loop, so you must assign the new value to denominator.
Also, there doesn't appear to any different between:
for (int i = 2; i < input + 2; ++i) {
...
}
and
for (int i = 0; i < input; ++i) {
...
}
So I would recommend start your index variable at 0 for readability's sake.
I am trying to use the non-restoring algorithm for computing the square root of a floating point number.
For instance, say x = 1001, the square root is 31.6386
I want to calculate this square root using the non-restoring method.
I tried following the method in the paper:
Implementation of Single Precision Floating Point Square Root on FPGAs
but it appears my result is slightly off by 1 bit. I'm not able to figure out why though.
For instance, the program I wrote below will produce the following results:
correct_result =
41FD1BD2
myresult =
41FD1BD1
error =
1.192093e-007
C++ version of the code :
#include <iostream>
#include <cmath>
using namespace std;
union newfloat{
float f;
int i;
};
int main () {
// Input number
newfloat x;
cout << "Enter Number: ";
cin >> x.f;
// Pull out exponent and mantissa
int exponent = (x.i >> 23) & 0xFF;
int mantissa = (x.i & 0x7FFFFF) | ((exponent && exponent) << 23);
// Calculate new exponent
int new_exponent = (exponent >> 1) + 63 + (exponent & 1);
// Shift right (paper says shift left but shift left doesn't work?)
if (exponent & 1) {
mantissa = mantissa >> 1;
cout << " Shifted right " << endl;
}
// Create an array with the bits of the mantissa
unsigned int D [48];
for (int i = 47; i >= 0; i--) {
if (i >= 24) {
D[i] = (mantissa >> (i-24)) & 1;
} else {
D[i] = 0;
}
}
// == Perform square root ==
// Set q24 = 0, r24 = 0 and then iterate from k = 23 to 0
int q[25] = {0}; // 25 element array, indexing ends at 24
int r[25] = {0};
for (int k = 23; k >= 0; k--) {
if (r[k+1] >= 0) {
r[k] = ((r[k+1] << 2) | (D[2*k+1] << 1) | D[2*k] ) - (q[k+1] << 2 | 1 );
} else {
r[k] = ((r[k+1] << 2) | (D[2*k+1] << 1) | D[2*k] ) + (q[k+1] << 2 | 0x3 );
}
if (r[k] >= 0) {
q[k] = (q[k+1] << 1) | 1;
} else {
q[k] = q[k+1] << 1;
}
if (k == 0) {
if (r[0] < 0) {
r[0] = r[0] + (q[0] << 1) | 1;
}
}
}
// Create quotient from LSBs of q[]
int Q = 0;
for (int i = 0; i <= 23; i++) {
Q = Q | ((q[i] & 1) << i);
}
// Option 1 Rounding
//if (r[0] > 0) // Works for 10, 1001, 1021, but not 1012
// Q = Q + 1;
// Option 2 Rounding (No rounding)
// Works for 1012, Doesn't work for 10, 1001, 1021
// Option 3 Rounding (Calculate the next 3 Quotient bits to get a guard round and sticky bit)
// Calculate correct result:
newfloat correct_result;
correct_result.f = sqrt(x.f);
// Form my result into a single number
newfloat myresult;
myresult.i = (new_exponent << 23) | (Q & 0x7FFFFF);
// Print results
cout << hex << "My result: " << myresult.i << endl;
cout << hex << "Correct: " << correct_result.i << endl;
return 0;
}
First let me highlight the relevant part from the paper:
You need to take another look at how the additions/subtractions are done. You code is performing it in regular double-numbers, but I think the algorithm is designed with integer modular arithmetic in mind.
So if you look at the example listed later in the paper, the computation of 0011 - 0101 wraps around to give 1110.
That could explain why you're getting the wrong results, I think :)
I was looking through the c++ version of your program and reading that document today. It seems to me that the algorithm is intended to provide both a quotient and a remainder. As in the example provided, he uses his algorithm to get the square root of 127, to which it provides a result of 11 + R 6. 112 + 6 = 127.
That was with an integer, but every data type has a limit to its precision. This leads me to believe that your program is executing as expected, its just that you've run out of precision, at least for the way the square root is being calculated, and for the data type being used. I expect you would find your minute "lost" precision in r[0].
I saw from the comments in the code that you intended to, or tried to calculate out extra precision. That seems like a reasonable path to try. Do note that, in addition to the other changes that would be required to do this, you would have to take out (or move) the check k == 0; since it modifies the remainder, which would mess up the loop.
I think the real question is what size precision is acceptable to you. For instance, the c++ sqrt function (and yours) are off by 0.00000002 on sqrt(2). No one seems to mind. Considering the program you wrote is off from the c++ sqrt function by less than that in the instances where it doesn't match. I spent the majority of the day breaking it down, testing the individual parts, and reviewing the subject matter, and couldn't find anything blatantly wrong. It seem close enough for government work to me.