Получение значения десятичной точки - PullRequest
1 голос
/ 07 октября 2011

У меня есть функция, которая должна преобразовать значение double в string one:

inline static string StringFromNumber(double val) // suppose val = 34.5678
{
 long integer = (long)val; // integer = 34
 long pointPart; // should be = 5678  how do I get it?
}

Как получить значение long для integer и pointPart?

Добавить: Мне нужна точность 17 чисел, с отбрасыванием нулей. Больше примеров:

val = 3.14 integer = 3 pointPart = 14

val = 134.4566425814748 integer = 134 pointPart = 4566425814748

У меня пока нет решения. Как я могу получить это?

Ответы [ 3 ]

3 голосов
/ 07 октября 2011

Строковый поток не даст вам, в частности, десятичную точку, но он преобразует все число в строку.

std::stringstream ss;
ss << val;
/*access the newly-created string with str()*/
return ss.str();
2 голосов
/ 07 октября 2011
long pointPart = static_cast<long>(val*10)%10;

10 за 2 знака после запятой ... 100 за 3 и т.д ...

String realPoint = (string)pointPart;

Плюс длинный не может содержать 17 цифр. это держит 10. так что вы, вероятно, хотите переменную типа float

1 голос
/ 07 октября 2011

Вы можете использовать modf для разделения целых и дробных частей. Затем вы можете умножить дробную часть на 1.0e17 и вызвать floor для правильного округления результатов до целочисленного компонента, а затем привести к unsigned long (дробная часть никогда не будет отрицательной, и это позволит вам максимизировать количество бит в целочисленном типе). Наконец, запустите цикл, чтобы обрезать нули на unsigned long. Например:

inline static string StringFromNumber(double val)
{
    double intpart, fracpart;
    fracpart = round((modf(val, &intpart)) * 1.0e17);

    long int_long = static_cast<long>(intpart);
    unsigned long frac_long = static_cast<long>(fracpart);

    //trim off the zeros
    for(unsigned long divisor = 10;;divisor *= 10)
    {
        if ((frac_long / divisor) * divisor != frac_long)
        {
            frac_long = frac_long / (divisor / 10);
            break;
        }
    }

    //...more code for converting to string
}

Обратите внимание, что этот код будет работать только до 17 десятичных знаков, если вы работаете на 64-битной платформе, а unsigned long определен как 64-битный целочисленный тип. В противном случае вы захотите изменить unsigned long на uint64_t. Также имейте в виду, что, поскольку числа с плавающей запятой являются приблизительными, а множитель равен 1.0e17, значение fracpart может не совпадать со значением части-части val ... другими словами, некоторые дополнительные цифры после любого необходимого округления.

...