Printing pi with large precision using GMP - c++

Right now I have this little code that I want to print pi to x decimals:
#include <iostream>
#include <gmpxx.h>
#include <math.h>
using namespace std;
int main()
{
mpf_set_default_prec(1000);
mpf_t pi;
mpf_init(pi);
mpf_set_d(pi, atan(1)*4);
cout << pi << endl;
}
I just sat default_prec to 1000 as I thought that would give me plenty of decimals, but no matter what I set it to, I only get 5. How can I print more?

The problem is atan(1)*4 will only be evaluated with single (or double) precision, since this part of the code has nothing to do with gmp and will use the standard c++ types. The program will evaluate atan(1)*4 first and then convert the result into an mpf_t.
On the GMP homepage there is a page on how to calculate Pi with many digits.

Related

C++ using math.h for sin returns "too many arguments in function call"

The user inputs a number, which is converted from characters to a double (the number is is 0.0 before input where it is updated to any number). I should then be able to convert this and find the sin value. At the moment I get an error "too many arguments in function call". I understand I need to convert the users input into radian but I can't seem to find a work around.
Here is a snippet of the code (my Pi and Logarithm functions work okay)
Using public as the function is accessed from another class.
I've looked at a lot of sources but here are two that helped:
http://www.cplusplus.com/reference/cmath/sin/
http://www.cplusplus.com/forum/beginner/144006/
I know I'm missing something obvious but I can't seem to put my finger on it.
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string>
#include <cmath>
class calculations {
public: double sin()
{
double radian = ((number1 * 180) / 2);
result = sin(radian);
return result;
}
}
Change the call to std::sin(radian). As written it's trying to call your sin function. Yours doesn't take any arguments, and it's being called with one argument, which is what the compiler is complaining about.

C++: Bessel function with non-integers

I have been trying to find a library/function that computes the Bessel function of the first kind, but with non-integer values.
I have the following program.
// Include standard libraries
#include <cstdlib>
#include <cmath>
#include <vector>
#include <array>
#include <iostream>
int main(int nargs, char* args[])
{
std::cout << "bessel function " << jn(5./2., 1.) << "\n" ;
}
However, it seems this function only calculates for integer values, so in the example I get the first Bessel function for n=2.
Anyone knows how I can determine the first Bessel function with non-integer values?
EDIT: I want to find a function in C++ that calculate J_(5/2)(x) for me.
boost library could be an answer. The Bessel function of the first kind is called cyl_bessel_j(v, x). Second kind cyl_neumann(v, x). Both works for real v.
Interesting alteranative here is the ROOT library from CERN with a lot of functions for scientific computation.

Read string math-formula into cpp as double from external input-file

I am relatively new to c++ coding and try to write a program to solve differential equations numerically. I use codeBlocks as the compiler for that and work under windows. The numeric solver already works well.
My program contains of some very long formulas which are created by mathematica and converted into cpp-language. Then the formulas are stored in a .txt-file.I can already read the formula as a string, but not use it to calculate things because the program has to interpret the formula as a double-type math and not as a string. The problem here is, that my formula does not contain only numbers, but letters as variables (their value is set in the program) and other mathematical symbols. That is why I think I cannot just use "atof" (http://www.cplusplus.com/reference/cstdlib/atof/?kw=atof) or other conversion functions. (If I am wrong at this point, I would be glad to learn how to use the function for this problem!)
Here is some example code from my little program:
//Program to solve ODEs
#include <iostream>
#include <math.h>
#include <cmath>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <time.h> //to measure the time
#include <stdio.h>
#include <conio.h>
using namespace std;
int main(void)
{
double k1=0;
ifstream file("Formelvu1.txt");//file with the fromula
string line;
stringstream longform;
while(getline(file, line)){ //read the formula and store them
longform << line; //store the string in "longform"
cout << longform;
}
return 0;
for(double t=0; t<10; t++){
k1 = (longform) * t; //simple operation with the formula
}
return 0;
}
This code doesn't work, becuase longform is no double...
longform is a string with something like: ab+pow(t,3)-sin(tb)/x.
I already found several questions related to this topic, but none of them was easy enough for me to understand or the right thing I want to do:
How can I convert string to double in C++?
From what I understand is this guy trying the nearest from what I wish to do:
Evaluate math formula from String using ScriptEngine
But I don't understand the code completely.
If it is useful for my problem: What does this part do?
try{
return (Double)engine.eval(tmp);
}
catch(Exception fexp)
{
}
I also heard about parser which can interpret the xpressions line muparser:
http://muparser.beltoforion.de/mup_eval.html
But I don't know if this would be more than I need...
I appreciate every answer/response and help with this problem.
Thank you!
You have to study carefully what is included in the basic C/C++ language and standard library and what not.
However, if you get a C++ compatible expression from mathematica, then you can let the C++ compiler do its work as in
double myfunc(double a, double b, double c, double t, double x) {
return
#include "Formelvu1.txt"
;
}

Using boost multiprecision with trigonometric function

Consider the following code which creates a multiprecision floating-point number 'a' by using boost.
How do I use boost library to invoke trigonometric functions?
For example, I hope to calculate sin(a).
#include <iostream>
#include "boost/multiprecision/cpp_bin_float.hpp"
using namespace std;
using namespace boost::multiprecision;
typedef number<backends::cpp_bin_float<24, backends::digit_base_2, void, boost::int16_t, -126, 127>, et_off> float32;
int main (void) {
float32 a("0.5");
return 0;
}
It looks like there is a limitation in the library. When the precision is dropped too low, the sin implementation no longer compiles.
Some intermediate calculations are being done in double precision. The assignment into the result type would be lossy and hence doesn't compile.
Your chosen type actually corresponds to cpp_bin_float_single. That doesn't compile.
As soon as you select cpp_bin_float_double (precision 53 binary digits) or higher, you'll be fine.
I suppose this limitation could be viewed as a bug in some respects. You might report it to the library devs, who will be able to judge whether the related code could use single-precision floats there without hurting the convergence of the sin approximation.
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <iostream>
using namespace std;
using namespace boost::multiprecision;
int main() {
cpp_bin_float_100 a = 1;
cout << setprecision(50) << endl;
cout << sin(a) << endl;
return 0;
}
I've verified digits with Wolfram Mathematica and they are correct:

cmath and math.h giving different answers

When I use the atan function from cmath and math on a floating point number, I seem to get different answers:
#include <cmath>
#include <math.h>
#include <iostream>
#include <iomanip>
int main() {
std::cout << std::setprecision(20) << atan(-0.57468467f) << std::endl;
std::cout << std::setprecision(20) << std::atan(-0.57468467f) << std::endl;
// I get:
// -0.52159727580733605823
// -0.52159726619720458984
}
Why does this happen? Does two libraries implement atan differently?
math.h's atan takes a double and returns a double, yet cmath's is overloaded so that a float argument (as used here) will be used as a float and yield a float result. Thus, the difference in output comes from using two different floating-point types. To make them use the same type, either remove the f at the ends of the numbers or change the first atan to atanf.