удвоение до строки с ++ с использованием математики - PullRequest
0 голосов
/ 14 февраля 2012

Я уже прочитал, выбросить предложения по Преобразование Double в строку в C ++ и Преобразование double в строку C ++? , но меня попросили создать функцию не-OOP, чтобы принятьв двойном, и вернуть std :: string, используя только математику.Я был в состоянии сделать это с помощью int в прошлом:

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;
}

, но проблема в том, что он использует проверку больше нуля, чтобы продолжать идти.Я продолжаю думать что-то вроде

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

Я думаю, что это должно идти до% 10, но я не уверен.каждый раз, когда я пытаюсь, я получаю целое число, а не десятичное число.

Например, я даю ему 125,5 (результат 251/2), и он выдает 1255. хотя в некоторых случаях я получаю только 125. любойпомощь была бы отличной.

Обновление: выбранное решение

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;
}

Ответы [ 3 ]

2 голосов
/ 14 февраля 2012

Вы должны использовать математику, вы не можете использовать ostringstream?

В противном случае вы можете сделать это в двух частях:

  1. Сначала получите целую часть.
  2. Тогда получите дробную часть.

Чтобы получить целую часть, просто приведите значение к int. Чтобы получить дробную часть, вычтите целочисленную часть из значения.

Если у вас есть дроби, умножьте на десять и получите это значение как целое число, которое будет однозначным целым числом.

Редактировать: Добавлен пример кода

#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;
}

Примечание: Вышеприведенная функция выявляет некоторые проблемы с числами с плавающей запятой на компьютерах. Например, значение 1.234 становится строкой "1.2339999999999999857891452847979962825775146484375".

1 голос
/ 14 февраля 2012

вы можете использовать ftoa в c, это выглядит примерно так

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);
}

или в cpp

#include <iomanip>

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

вы также можете рассмотреть возможность использования setprecision для установки количества десятичных цифр:

out << fixed << setprecision(2) << val;
0 голосов
/ 14 февраля 2012

оставьте свой toString (int) и перегрузите его с помощью toString (double) следующим образом

#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);
}
...