Anonymous - 12 days ago 6x
C++ Question

# Convert Boost Multi-precision Float to String maintaining precision

How can I convert from an Boost's multiprecision float to a string without it being truncated?

I have the following code:

``````#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <cmath>
#include <iomanip>

int main() {
const int precision = 100;
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<precision> > absFloat;

std::cout << "Iterations: ";
int iterations;
std::cin >> iterations;

absFloat wnew = 0.0, x;

std::cout << "W(x), x = ";
std::cin >> x;

std::cout << std::setprecision(precision);

std::string firstStr, secondStr;

for(int i = 0; i <= iterations; i++){
firstStr = boost::lexical_cast<std::string>(wnew);
wnew = ((wnew * wnew) + x * exp(-wnew))/(1+wnew);
secondStr = boost::lexical_cast<std::string>(wnew);
if(firstStr == secondStr)
break;
std::cout << "\n" << i << " - " << wnew << "\n";
}

std::cout << "\n" << firstStr << std::endl;
std::cout << secondStr << std::endl;

return 0;
}
``````

What it actually does is not very crucial as far as this question is concerned, but simply put it approximates the value of the Lambert W function using a simplified version of the Newtonâ€“Raphson method.

The code I am asking about is inside the
`for`
loop:

``````for(int i = 0; i <= iterations; i++){
firstStr = boost::lexical_cast<std::string>(wnew);
wnew = ((wnew * wnew) + x * exp(-wnew))/(1+wnew);
secondStr = boost::lexical_cast<std::string>(wnew);
if(firstStr == secondStr)
break;
std::cout << "\n" << i << " - " << wnew << "\n";
}
``````

Here I am converting from an arbitrary-precision floating-point number (in this case it has 100 decimals
`const int precision = 100`
) to a string. The value of
`precision`
will be manually changed constantly.

I convert the value of
`wnew`
to a string before and after calculations, then compare the two strings. If they are identical, the
`for`
loop is broken. This is not the result I am getting.

Here is the result with
`iterations`
set to
`20`
and
`x`
set to
`1`
:

``````Iterations: 20
W(x), x = 1

0 - 1

1 - 0.6839397205857211607977618850807304337229055655158839172539184008487307478724499016785736371729598219

2 - 0.5774544771544497158879277307209708744246953720136943334618725831739970553254359545244940341535829055

3 - 0.5672297377301170424199788873305659381989740529912345334258918256943726362413406459666277736815827773

4 - 0.5671432965302959290104061393322652388244468110017561469052367139960666960291476041675058924102131759

0.567143
0.567143

RUN SUCCESSFUL (total time: 1s)
``````

As you can see, the strings are the same after the 4th iteration. But in fact the numbers are the same after the 8th iteration! Here is the rest of the output without the if statement break:

``````Iterations: 20
W(x), x = 1

0 - 1

1 - 0.6839397205857211607977618850807304337229055655158839172539184008487307478724499016785736371729598219

2 - 0.5774544771544497158879277307209708744246953720136943334618725831739970553254359545244940341535829055

3 - 0.5672297377301170424199788873305659381989740529912345334258918256943726362413406459666277736815827773

4 - 0.5671432965302959290104061393322652388244468110017561469052367139960666960291476041675058924102131759

5 - 0.5671432904097839036821986273638501915396349920558000709178381348786164164929847042875694697488581049

6 - 0.5671432904097838729999686622103563208086217342023287565768851248326011789240991181028762582526321268

7 - 0.5671432904097838729999686622103555497538157871865125081351310792235327403215041862450323133272582057

8 - 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946

9 - 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946

10 - 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946

11 - 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946

12 - 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946

13 - 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946

14 - 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946

15 - 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946

16 - 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946

17 - 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946

18 - 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946

19 - 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946

20 - 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946

0.567143
0.567143

RUN SUCCESSFUL (total time: 1s)
``````

Why is the multi-precision float being truncated when being converted to a string? How can I convert from an Boost's multiprecision float to a string without it being truncated?

Found the solution on my own, I was over-complicating it. To convert from a Boost multiprecision float to a string is actually pretty simple:

``````for(int i = 0; i <= iterations; i++){
std::string firstStr = wnew.convert_to<std::string>();
wnew = ((wnew * wnew) + x * exp(-wnew))/(1+wnew);
std::string secondStr = wnew.convert_to<std::string();
if(firstStr == secondStr)
break;
std::cout << "\n" << i << " - " << wnew << "\n";
}
``````

Using `convert_to` also revealed the reason why it was not stopping after the 8th iteration. The numbers are actually longer than they were being displayed as, so after each iteration they were all different.