0

I have already read throw the suggestions on Converting Double to String in C++ and Convert double to string C++? but I have been asked to create a function non-OOP to take in a double, and return a std::string using only math. I have been able to do this with an int in the past wich:

std::string toString(int value) {
    string result = "";
    bool negative = false;
    if ( value < 0 ) {
        negative = true;
        value *= (-1);
    }
    do {
        string tmpstr = "0";
        tmpstr[0] += value%10;
        result = tmpstr + result;
        value /= 10;
    } while ( value != 0);
    if ( negative ) {
        result = "-" + result;
    }
    return result;
}

but the problem is that it uses a check for greater then zero to keep going. I keep thinking something like

if ( value < 0 ){
    value *= 10;
}

I thing that this should go before the %10 but I'm not sure. every time I try I get a whole number, and not the decimal.

for example I give it 125.5 (result of 251/2), and it outputs 1255. though in some cases I only get 125. any help would be great.

Update:chosen solution

std::string toString(float value){
    bool negative = false;
    if ( value < 0 ) {
        negative = true;
        value *= (-1);
    }

    int v1 = value;         // get the whole part
    value -= v1;            // get the decimal/fractional part
    //convert and keep the whole number part
    std::string str1 = toString(v1); 

    std::string result = "";
    do {
        value *= 10;
        int tmpint = value;
        value -= tmpint;
        string tmpstr = "0";
        tmpstr[0] += tmpint % 10;
        result = tmpstr + result;
        value /= 10;
    } while ( value != 0);

    result = str1 + "." + result;

    if ( negative ) {
        result = "-" + result;
    }
    return result;
}
Community
  • 1
  • 1
gardian06
  • 1,496
  • 3
  • 20
  • 34

3 Answers3

2

Do you have to use math, can't you use an ostringstream?

Otherwise you can do it in two parts:

  1. First get the integer part.
  2. Then get the fraction part.

To get the integer part, just cast the value to an int. To get the fraction part by itself, subtract the integer part from value.

When you have the fractions, multiply by ten and get the that value as an integer, which will be a single-digit integer.

Edit: Added code sample

#include <string>
#include <algorithm>   // for std::reverse
#include <cmath>       // for std::fabs

// ...

std::string toString(double value)
{
    // Get the non-fraction part
    int ival = int(value);

    // Get the fraction part
    double frac = std::fabs(value - ival);

    // The output string
    std::string str;

    // Is the number negative?
    bool negative = false;

    // Convert the non-fraction part to a string
    if (ival < 0)
    {
        negative = true;
        ival = -ival;
    }

    while (ival > 0)
    {
        str += char((ival % 10) + '0');
        ival /= 10;
    }

    // The integer part is added in reverse, so reverse the string to get it right
    std::reverse(str.begin(), str.end());

    if (negative)
        str = std::string("-") + str;

    if (frac > 0.0)
    {
        str += '.';

        // Convert the fraction part
        do
        {
            frac *= 10;
            ival  = int(frac);
            str  += char(ival + '0');
            frac -= ival;
        } while (frac > 0.0);
    }

    return str;
}

Note: The above function exposes some of the problems floating point numbers have on computers. For example, the value 1.234 becomes the string "1.2339999999999999857891452847979962825775146484375".

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • value can be any number that a double can be [+-1.7E(+-308)] will not only ever be 1 decimal value that was example – gardian06 Feb 14 '12 at 06:52
  • I'm sure there's a much better way, but you could just multiply by 10 until the limit of the fractional component is reached and then truncate the zeroes from the end of the string. – Pochi Feb 14 '12 at 07:10
  • @gardian06 Try the function I just added. – Some programmer dude Feb 14 '12 at 07:17
  • 1
    Found a bug: reversing with a negative number would make the `-` appear at the end of the integer portion. – Pochi Feb 14 '12 at 07:36
  • this seems cleaner then the solution that I think I will go with. the reason for going with a different solution is the teacher specified in the assignment requirements "use only math to convert a floating point (double) number to a string, no string function calls are allowed" – gardian06 Feb 14 '12 at 08:00
  • thanks for the help. you gave great incite into finding the solution. for that this answer will be accepted, and code fragment saved. sorry I didn't end up using it. dang requirements – gardian06 Feb 14 '12 at 08:10
1

you can use ftoa in c, it looks something like this

void ftoa(char * buf, double f, char pad)
{
    char * p;

    f = (f*100.0 + 0.5)/100.0;        // round
    p = itoa(buf,f,pad);
    *p++ = '.';

    f -= (unsigned int) f;
    f = f * 100.0;
    itoa(p,f,2);
}

or in cpp

#include <iomanip>

std::string doubleToString(double val)
{
   std::ostringstream out;
   out << std::fixed << val;
   return out.str()
}

you might also consider using setprecision to set the number of decimal digits:

out << fixed << setprecision(2) << val;
P M
  • 837
  • 1
  • 10
  • 17
0

keep your toString(int), and overload with toString(double) in this way

#include <cmath>

std::string toString(int i) {...}
std::string toString(double d)
{
   const K = 1000000; // controls how many digits display in the fractional part
   return toString(int(d)) + "." + toString(int(fabs(d) * K) % K);
}
CapelliC
  • 59,646
  • 5
  • 47
  • 90