I have two numbers which are 32 digit decimal floating point numbers, like 1.2345678901234567890123456789012, I want to get the multiplication which is also 32 digit decimal floating point number. Is there any efficient way to do this?
Just use boost::multiprecision
. You can use arbitrary precision but there is a typedef
cpp_bin_float_50
which is a float
with 50 decimal places.
Example for multiplying to big decimal numbers:
#include <iostream>
#include <boost/multiprecision/cpp_bin_float.hpp>
int main(){
boost::multiprecision::cpp_bin_float_50 val1("1.2345678901234567890123456789012");
boost::multiprecision::cpp_bin_float_50 val2("2.2345678901234567890123456789012");
std::cout << std::setprecision(std::numeric_limits< boost::multiprecision::cpp_bin_float_50>::max_digits10);
std::cout << val1*val2 << std::endl;
}
Output:
2.7587257654473404640618808351577828416864868162811293
Use the usual grade school algorithm (long multiplication). If you used 3 ints (instead of 4):
A2A1A0 * B2B1B0 = A2*B2 A2*B1 A2*B0
A1*B2 A1*B1 A1*B0
A0*B2 A0*B1 A0*B0
Every multiplication will have a 2-int result. You have to sum every column on the right side, and propagate carry. In the end, you'll have a 6-int result (if inputs are 4-int, then the result is 8-int). You can then round this 8-int result. This is how you can handle the mantissa part. The exponents should just be added together.
I recommend you to divide a problem into two parts:
You'll need something like this as a workhorse (note that this code assumes that int is 32-bit, long long is 64-bit):
void wideMul(unsigned int &hi, unsigned int &lo, unsigned int a, unsigned int b) {
unsigned long long int r = (unsigned long long int)a*b;
lo = (unsigned int)r;
hi = (unsigned int)(r>>32);
}
Note: that if you had larger numbers, there are faster algorithms.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.