Define multiprecision pi in boost:multiprecision - c++
I need pi (3.1415...) in arbitrary (but fixed) precision in boost::multiprecision.
The constants in boost::math::constants are only defined up to a fixed number of digits, as pointed out in this answer, so I need to compute it by myself.
Because I'm using this number often and with a very large number of digits, I would like to compute it in runtime only once. what would be a simple yet fast way to have it?
I thought using
typedef number<cpp_dec_float<PRECISION> > mpfloat; // PRECISION is compile time.
const int PI = atan(mpfloat(1))*4;
but I'm not sure this is a common idiom for it.
In c++14 you can use a template variable (http://en.cppreference.com/w/cpp/language/variable_template).
Note that you can already have what you want by including
#include <boost/multiprecision/detail/default_ops.hpp>
That header ends up including constants.hpp which defines template <class T> const T& get_constant_pi().
This is the c++03 idiom for template variables already (as it stores a function-local static result value).
calc_pi has the first 1100 digits hardcoded, and the rest is calculated via optimized formulae if required.
Demo with 50 and 5000 digits:
Live On Coliru (c++14)
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/detail/default_ops.hpp>
#include <boost/multiprecision/number.hpp>
#include <iostream>
namespace {
namespace bmp = boost::multiprecision;
template <int N> bmp::number<bmp::cpp_dec_float<N> > const my_const_pi
= bmp::default_ops::get_constant_pi<bmp::cpp_dec_float<N> >();
}
int main() {
std::cout << std::setprecision(50) << my_const_pi<50> << "\n";
std::cout << std::setprecision(5000) << my_const_pi<5000> << "\n";
}
Prints
3.1415926535897932384626433832795028841971693993751
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275900994657640789512694683983525957098258226205224894077267194782684826014769909026401363944374553050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362226260991246080512438843904512441365497627807977156914359977001296160894416948685558484063534220722258284886481584560285060168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288797108931456691368672287489405601015033086179286809208747609178249385890097149096759852613655497818931297848216829989487226588048575640142704775551323796414515237462343645428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435064302184531910484810053706146806749192781911979399520614196634287544406437451237181921799983910159195618146751426912397489409071864942319615679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539057962685610055081066587969981635747363840525714591028970641401109712062804390397595156771577004203378699360072305587631763594218731251471205329281918261861258673215791984148488291644706095752706957220917567116722910981690915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398315019701651511685171437657618351556508849099898599823873455283316355076479185358932261854896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923233260972997120844335732654893823911932597463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100449293215160842444859637669838952286847831235526582131449576857262433441893039686426243410773226978028073189154411010446823252716201052652272111660396665573092547110557853763466820653109896526918620564769312570586356620185581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318586769751456614068007002378776591344017127494704205622305389945613140711270004078547332699390814546646458807972708266830634328587856983052358089330657574067954571637752542021149557615814002501262285941302164715509792592309907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111790429782856475032031986915140287080859904801094121472213179476477726224142548545403321571853061422881375850430633217518297986622371721591607716692547487389866549494501146540628433663937900397692656721463853067360965712091807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862947265473642523081770367515906735023507283540567040386743513622224771589150495309844489333096340878076932599397805419341447377441842631298608099888687413260472
I'd recommend just putting the value of pi into your source code as a constant with however many digits you need.
Define it as a static within a struct.
Related
Printing float and double values using cout in C++
For the following code: #include <iostream> using namespace std; class Hall { public: double cost; }; int main() { Hall hall; hall.cost=10000.50; cout<<hall.cost; return 0; } Why does this code output 10000.5 and not 10000.50, can someone explain the logic behind this?
can someone explain the logic behind this? The default behaviour is not show any trailing zeroes.
double (and floating-point variables in general) don't store a specific spelling of the number (base-10 or otherwise). That would be way too inefficient, and the ability to store meaningless zeroes would waste memory. Instead, the numbers are encoded in a certain binary format. Printing them reproduces the base-10 spelling from binary.
By default, C++ does not display trailing zeros, however the standard library <iomanip> can be used along with std::fixed from <iostream>. Here is an example: #include <iostream> #include <iomanip> int main() { double myVar = 123.4; std::cout << std::fixed << std::setprecision(2); // 2 trailing digits std::cout << myVar << std::endl; return 0; }
C++ auto on int16_t casts to integer
I am pretty new to C++17 and am attempting to understand the decltype keyword and how it pairs with auto. Below is a snippet of code that produces an unexpected result. #include <typeinfo> #include <iostream> #include <algorithm> using namespace std; int main() { int16_t mid = 4; auto low = mid - static_cast<int16_t>(2); auto hi = mid + static_cast<int16_t>(2); int16_t val; cin >> val; val = std::clamp(val,low,hi); return 0; } Surprisingly, the compiler tells me there is a mismatch in clamp and that low and high are int. If I change auto to int16_t all is good in the world and all the types are int16_t as expected. The question I'm posing is, why does auto cast low and hi to int when all of the types are int16_t? Is this a good use case for decltype? Even after reading cppreference.com, I don't fully understand how decltype works, so excuse my ignorance.
The problem isn't with auto here. When you subtract two int16_t values, the result is an int. We can demonstrate it with this code here: #include <iostream> #include <cstdint> using namespace std; template<class T> void print_type(T) { std::cout << __PRETTY_FUNCTION__ << std::endl; } int main() { int16_t a = 10; int16_t b = 20; print_type(a); print_type(b); print_type(a - b); return 0; } a and b are both short ints, but when you add or subtract them it produces a regular int. This is to help prevent overflow / and is also for backwards compatibility.
This phenomenon is called the usual arithmetic conversions. It is defined in the C and C++ standards and (roughly said) converts anything smaller than an int to an int. It converts larger types as well. Take some time and read about it, you'll need it quite often.
Is there any variable like BigInteger, but as floating point?
I saw, that there are libraries, that offer data types like BigInterger, but I need one, that contains a variable type, that is "big" (means: that can handle very high values) but also I need the possibility to divide it by another high number, so it wouldn't work with BigInterger..
If you need more precision in your calculations, you can use this library for big nums. Its simple and easy to start and created in C++ with template classes. #include <ttmath/ttmath.h> #include <iostream> int main() { // Big<exponent, mantissa> ttmath::Big<1,2> a,b,c; a = "1234.3323454"; b = "3456.1234534"; c = a*b; std::cout << c << std::endl; }
Physical Boost.Units User Defined Literals
Now that we soon have user defined literals (UDL), in GCC 4.7 for example, I'm eagerly waiting for (physical) unit libraries (such as Boost.Units) using them to ease expression of literals such as 1+3i, 3m, 3meter or 13_meter. Has anybody written an extension to Boost.Units using UDL supporting this behaviour?
No one has come out with such an extension. Only gcc (and possibly IBM?) has UDL so it might be a while. I'm hoping some kind of units makes it into tr2 which is starting about now. If that happens I'm sure UDL for units will come up. This works: // ./bin/bin/g++ -std=c++0x -o units4 units4.cpp #include <boost/units/unit.hpp> #include <boost/units/quantity.hpp> #include <boost/units/systems/si.hpp> using namespace boost::units; using namespace boost::units::si; quantity<length, long double> operator"" _m(long double x) { return x * meters; } quantity<si::time, long double> operator"" _s(long double x) { return x * seconds; } int main() { auto l = 66.6_m; auto v = 2.5_m / 6.6_s; std::cout << "l = " << l << std::endl; std::cout << "v = " << v << std::endl; } I think it wouldn't be too hard to go through you favorite units and do this. Concerning putting these in a library: The literal operators are namespace scope functions. The competition for suffixes is going to get ugly. I would (if I were boost) have namespace literals { ... } Then Boost users can do using boost::units::literals; along with all the other using decls you typically use. Then you won't get clobbered by std::tr2::units for example. Similarly if you roll your own.
In my opinion there is not much gain in using literals for Boost.Units, because a more powerful syntax can still be achieved with existing capabilities. In simple cases, looks like literals is the way to go, but soon you see that it is not very powerful. For example, you still have to define literals for combined units, for example, how do you express 1 m/s (one meter per second)? Currently: auto v = 1*si::meter/si::second; // yes, it is long but with literals? // fake code using namespace boost::units::literals; auto v = 1._m_over_s; // or 1._m/si::second; or 1._m/1_s // even worst A better solution can be achieved with existing features. And this is what I do: namespace boost{namespace units{namespace si{ //excuse me! namespace abbreviations{ static const length m = si::meter; static const time s = si::second; // ... } }}} // thank you! using namespace si::abbreviations; auto v = 1.*m/s; In the same way you can do: auto a = 1.*m/pow<2>(s); or extend the abbreviations more if you want (e.g. static const area m2 = pow<2>(si::meter);) What else beyond this do you want? Maybe a combined solution could be the way auto v = 1._m/s; // _m is literal, /s is from si::abbreviation combined with operator/ but there will be so much redundant code and the gain is minimal (replace * by _ after the number.) One drawback of my solution is that it polutes the namespace with common one letter names. But I don't see a way around that except to add an underscore (to the beginning or the end of the abbreviation), as in 1.*m_/s_ but at least I can build real units expressions.
How to precompute array of values?
Is there a way to pre-compute an array of values based on templates? In the following example I would like the 'powers_of_2' array to have 256 values computed at compile-time if that is possible without having to type all of the values. #include <iostream> using namespace std; template <int X, char Y> struct power { enum { value = X * power<X,Y-1>::value }; }; template <int X> struct power<X,1> { enum { value = X }; }; template <int X> struct power<X,0> { enum { value = 1 }; }; int _tmain(int argc, _TCHAR* argv[]) { int powers_of_2[] = { power<2,0>::value, power<2,1>::value, ..., power<2,255>::value }; cout << powers_of_2[1] << endl; return 0; }
Unless you plan on using a big integer package you will overflow the integer type at 2^32 (or 2^64, depending), but to answer your real question look at this wikipedia article on template metaprogramming.
That is exactly what a macro is useful for...
Holding the value 2^255 would require 32 bytes. This cannot be held in an int; you'd need a char array typedef unsigned char BYTE32[32]; BYTE32 powers_of_2[256] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0}, // : // : {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} };
What I do in situations like that is write a small program that generates and writes to a file the array initialization in C++ source and then #include that file. This technique is simple and effective.
You could easily write a small script to prepopulate the array for you using your preferred scripting language. Depending on the compiler and preprocessor you use, you should also be able to do it as a macro.
I agree with Lokkju. It is not possible to initialize the array by only means of template metaprogramming and macros in this case are very useful. Even Boost libraries make use of macros to implement repetitive statements. Examples of useful macros are available here: http://awgn.antifork.org/codes++/macro_template.h