How to use boost multiprecision to calculate large int and double numbers - c++

I wanted to do calculation among large integers and double, for example,
1245.....889 * 3.14
I think we cannot construct a cpp_int from 3.14 because of
http://www.boost.org/doc/libs/1_56_0/libs/multiprecision/doc/html/boost_multiprecision/tut/conversions.html
Also I am not sure if I can use cpp_dec_float because cpp_dec_float needs to specify the number of significant bits which cannot be arbitrarily large.
Does it mean I should use cpp_rational? But I have to convert 3.14 in a rational number first like?
how can I extract the mantissa of a double
Do we have any better way to represent double like 3.14 and large int together?
Thank you,

Your question seems amply confused, but here goes:
You can use the gmp_float with dynamic precision by specifying 0 for the precision:
Live On Coliru
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/gmp.hpp>
#include <iostream>
int main() {
using Int = boost::multiprecision::cpp_int;
using Float = boost::multiprecision::number<boost::multiprecision::gmp_float<0>>;
Float fake_pi;
boost::multiprecision::default_ops::calc_pi(fake_pi.backend(), 2000);
Int value("12345678901234567890123456789012345678901234567890");
std::cout << std::fixed << value << " * " << fake_pi << " = " << Float(value.convert_to<Float>() * fake_pi);
}
Prints
12345678901234567890123456789012345678901234567890 * 3.141593 = 38785094139697029053093797030280437291228399875653.959648

Related

How ceil function works in c++?

When I execute this code the value of ans1, ans2 is 50002896 and 50005000.
I know there is some issues with ceil function but was not able to figure out the exact cause.
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long ans1 = 0, ans2 = 0;
for (long long i = 1; i <= 10000; i++)
{
ans1 = ans1 + ceil((float)i / 1);
ans2 = ans2 + i;
}
cout << ans1 << " " << ans2 << endl;
}
The source of the problem is not the ceil function, but rather that not all integers can be represented accuratly as floating point values.
Some more info about floating point representation: Wikipedia IEEE 754. And a related post: Which is the first integer that an IEEE 754 float is incapable of representing exactly?.
The following code is a minimal demonstration of the same issue that causes your issue:
float f1 = 100000000;
f1++;
std::cout << std::to_string(f1) << std::endl;
[Wrong] Output (expected: +1):
100000000.000000
One approach would be to use double instead of float.
This will not solve the principle issue, but will make the range of representable integers a lot bigger:
double f1 = 100000000;
f1++;
std::cout << std::to_string(f1) << std::endl;
Output:
100000001.000000
Some side notes:
better to avoid #include <bits/stdc++.h> - see here: Why should I not #include <bits/stdc++.h>?.
better to avoid using namespace std - see here Why is "using namespace std;" considered bad practice?.
First, try to use specific headers like #include , in this case, .because #include <bits/stdc++.h> will bring lots of junk.
So the issue is with float not ceil explained below
floating-point values do not represent exact values.
Code:-
#include <iostream>
#include <iomanip>
using namespace std;
// Driver Code
int main()
{
float num1 = 10000.29;
float num2 = 10000.2;
// Output should be 0.0900000000
cout << std::setprecision(15)
<< (num1 - num2);
return 0;
}
Output :-
0.08984375

Fixed point library prints less-accurate value than multiplying two floats

I'm using this C++ fixed point library:
https://github.com/MikeLankamp/fpm
My program multiplies two values together and outputs them, first using fixed point, second using primitive floats:
#include <fpm/fixed.hpp>
#include <fpm/ios.hpp>
#include <iostream>
int main()
{
fpm::fixed_16_16 x{2.2};
fpm::fixed_16_16 y{ 2 };
std::cout << (x * y) << std::endl;
std::cout << (2.2 * 2) << std::endl;
}
The fixed-point library outputs a less-accurate result than just multiplying two floats:
4.3999
4.4
What am I doing wrong?

Precision rounding problem with boost multiprecision

I want to multiply number 123456789.123456789 by 1000000000.0 and as a result of this operation I expect 123456789123456789 as int or float 123456789123456789.0, but I got:
res: 123456789123456791.04328155517578125
int_res: 123456789123456791
Should I do it in other way ?
#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
namespace bmp = boost::multiprecision;
int main()
{
bmp::cpp_dec_float_100 scalar{1000000000.0};
bmp::cpp_dec_float_100 a{123456789.123456789};
bmp::cpp_dec_float_100 res = a * scalar;
bmp::cpp_int int_res = res.convert_to<bmp::cpp_int>();
std::cout << " res: " << res.str() << std::endl;
std::cout << "int_res: " << int_res.str() << std::endl;
return 0;
}
Code: https://wandbox.org/permlink/xB8yBWuzzGvQugg7
See https://www.boost.org/doc/libs/1_79_0/libs/multiprecision/doc/html/boost_multiprecision/tut/floats/fp_eg/floatbuiltinctor.html.
You are initialising a with a double literal. 123456789.123456789 can't be represented by a double so you get the closest approximation which is 123456789.12345679104328155517578125. If you want to initialise precisely use a string literal instead:
bmp::cpp_dec_float_100 a{"123456789.123456789"};
You are using the double literal to initialise a which can't give you the value you want for the obvious reason, use String literal instead, it will be good to go.

boost lexical cast double to string giving invalid results

I am trying this:
std::cout << boost::lexical_cast<std::string>(0.0009) << std::endl;
and expecting the output to be:
0.0009
But the output is:
0.00089999999999999998
g++ version: 5.4.0, Boost version: 1.66
What can I do to make it print what it's been given.
You can in fact override the default precision:
Live On Coliru
#include <boost/lexical_cast.hpp>
#ifdef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
# error unsupported
#endif
template <> struct boost::detail::lcast_precision<double> : std::integral_constant<unsigned, 5> { };
#include <string>
#include <iostream>
int main() {
std::cout << boost::lexical_cast<std::string>(0.0009) << std::endl;
}
Prints
0.0009
However, this is both not supported (detail::) and not flexible (all doubles will come out this way now).
The Real Problem
The problem is loss of accuracy converting from the decimal representation to the binary representation. Instead, use a decimal float representation:
Live On Coliru
#include <boost/lexical_cast.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <string>
#include <iostream>
using Double = boost::multiprecision::cpp_dec_float_50;
int main() {
Double x("0.009"),
y = x*2,
z = x/77;
for (Double v : { x, y, z }) {
std::cout << boost::lexical_cast<std::string>(v) << "\n";
std::cout << v << "\n";
}
}
Prints
0.009
0.009
0.018
0.018
0.000116883
0.000116883
boost::lexical_cast doesn't allow you to specify the precision when converting a floating point number into its string representation. From the documentation
For more involved conversions, such as where precision or formatting need tighter control than is offered by the default behavior of lexical_cast, the conventional std::stringstream approach is recommended.
So you could use stringstream
double d = 0.0009;
std::ostringstream ss;
ss << std::setprecision(4) << d;
std::cout << ss.str() << '\n';
Or another option is to use the boost::format library.
std::string s = (boost::format("%1$.4f") % d).str();
std::cout << s << '\n';
Both will print 0.0009.
0.0009 is a double precision floating literal with, assuming IEEE754, the value
0.00089999999999999997536692664112933925935067236423492431640625
That's what boost::lexical_cast<std::string> sees as the function parameter. And the default precision setting in the cout formatter is rounding to the 17th significant figure:
0.00089999999999999998
Really, if you want exact decimal precision, then use a decimal type (Boost has one), or work in integers and splice in the decimal separator yourself. But in your case, given that you're simply outputting the number with no complex calculations, rounding to the 15th significant figure will have the desired effect: inject
std::setprecision(15)
into the output stream.

Missing decimals when printing

Below is some simple code I am working with:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
float f = 1.66f;
int d = (int)f;
double g = (double)d;
cout.precision(6);
cout<<g<<"\n";
}
I want it to print 1.000000 but it prints only 1. But, even after upgradation of int to double, doesn't it automatically convert it to an integer value?
You can add cout << std::fixed;
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
float f = 1.66f;
int d = (int)f;
double g = (double)d;
cout.precision(6);
cout << std::fixed;
cout<<g<<"\n";
}
and you get 1.000000
Explanations (edit)
When you use std::fixed :
When floatfield is set to fixed, floating-point values are written
using fixed-point notation: the value is represented with exactly as
many digits in the decimal part as specified by the precision field
(precision) and with no exponent part.
When you use the std::defaultfloat (the one you are using) :
When floatfield is set to defaultfloat, floating-point values are
written using the default notation: the representation uses as many
meaningful digits as needed up to the stream's decimal precision
(precision), counting both the digits before and after the decimal
point (if any).
That's why the following .000000 are considered irrevelant !
(If you had 1.00001 it would have been printed)
Setprecision sets how precise the result has to, e.g.
std::cout << (1.f)/6 << std::endl; // prints 0.166667
std::cout.precision(7);
std::cout << (1.f)/6 << std::endl; // prints 0.1666667
But it does not require that 0's are printed out, consider:
std::cout.precision(5);
std::cout << 1.1110f << std::endl; // prints 1.111
std::cout << 1.1111f << std::endl; // prints 1.1111
And as coincoin suggests the solution to get 0's printed out is to use std::fixed!