How to implement std :: to_string for floating point?

3

This question may seem more like a request, but I've been researching it for 2 months and I do not know how to solve it. I need to implement std::to_string in C ++ ( without headers ) in a way that accepts decimal values ( float, double ). Which way is most appropriate? Note that I'm implementing my own std::string .

    
asked by anonymous 29.01.2014 / 20:39

3 answers

2

Since you did not specify any constraints for the implementation, the simplest way to do it would be:

std::string to_string(float f) {
    std::ostringstream buffer;
    buffer << f;
    return buffer.str();
}

And the same then for double and long double .

It would also be valid to have an array of char large enough and use sprintf .

EDIT:

As stated in the comments, this is to be an implementation in the arm. One algorithm I quickly implemented to do this is as follows:

std::string to_string(double value, unsigned precision=2) {

    const bool negative = value < 0;
    if (negative) {
        value *= -1;
    }

    //Move a casa decimal para a esquerda o quanto for necessário
    for (unsigned i=0; i<precision; ++i) {
        value *= 10;
    }

    //Converte para inteiro e calcula quantos dígitos vai ter
    unsigned long long i_value = value;
    int digits_count = 0;
    for (unsigned long long v=i_value; v!=0; v /= 10) {
        ++digits_count;
    }

    std::string result;
    result.resize(digits_count+1); //+1 para o '.';

    //Converte para string e põe o '.' no lugar necessário
    int prec_counter = precision;
    for (int pos = result.size()-1; pos >= 0; --pos) {

        if (prec_counter == 0) {
            result[pos] = '.';
        }
        else {
            int digit = i_value % 10;
            i_value /= 10;
            result[pos] = '0' + digit;
        }
        --prec_counter;
    }

    //Remove zeros à direita depois do . decimal
    if (precision > 0) {
        while (result.back() == '0') {
            result.pop_back();
        }
        if (result.back() == '.') {
            result.pop_back();
        }
    }

    return (negative ? "-" : "") + result;
}

This is a simple and limited algorithm, but it can serve as a basis for something more elaborate. I have not tested much, and it does not treat special cases like NAN . I'm assuming your std::string has the functions I've used.

    
29.01.2014 / 20:53
4

Why do not you use something ready? Boost's lexical_cast resolves.

using std::string;
using boost::lexical_cast;

int i = 10;    
string x = lexical_cast<string>(i);

link

    
30.01.2014 / 14:43
1

The simplest way to implement the function is to rely on the std::stringstream that uses the std::ostream operators that will already be implemented for the standard and many of the custom types. That would make your function work for most types. An example implementation:

#include <string>
#include <sstream>

template <typename T>
std::string to_string(const T& value) {
    std::stringstream ss;
    ss << value;
    return ss.str();
}
    
29.01.2014 / 20:47