Подтвердить что ты не робот

С++: каков оптимальный способ преобразования double в строку?

Каков оптимальный способ достижения такого же результата?

void foo(double floatValue, char* stringResult)
{
    sprintf(stringResult, "%f", floatValue);
}
4b9b3361

Ответ 1

Я бы, вероятно, пошел с тем, что вы предложили в своем вопросе, так как нет встроенной функции ftoa(), и sprintf дает вам контроль над форматом. Поиск google для "ftoa asm" дает некоторые полезные результаты, но я не уверен, что вы хотите зайти так далеко.

Ответ 2

Я уверен, что кто-то скажет boost:: lexical_cast, так что пойдите для этого, если вы используете boost, но это в основном так же, как и в любом случае:

 #include <sstream>
 #include <string>

 std::string doubleToString(double d)
 {
    std::ostringstream ss;
    ss << d;
    return ss.str();
 }

Обратите внимание, что вы можете легко сделать это в шаблон, который работает на все, что может быть вставлено в поток (а не просто удваивается).

Ответ 5

В dinkumware STL строковый поток заполняется библиотекой sn snff.

Таким образом, использование форматирования snprintf напрямую будет сопоставимо с частью форматирования STL. Но кто-то однажды сказал мне, что все больше или равно сумме его известных частей.

Поскольку это зависит от платформы, будет ли stringstream выполнять выделение (и я уверен, что DINKUMWARE НЕ ЕСТЬ включает небольшой буфер в stringstream для конверсий отдельных элементов, таких как ваши), это действительно сомнительно, что НИЧЕГО, что требует распределение (ESPECIALLY if MULTITHREADED) может конкурировать с snprintf.

Фактически (форматирование + распределение) имеет шанс быть действительно ужасным, так как выделение и релиз вполне могут потребовать 2 полных цикла чтения-модификации-записи в многопоточной среде, если только реализация распределения не имеет поточную локальную небольшую кучу.

Говоря, что если я действительно обеспокоен производительностью, я бы посоветовал некоторые из других комментариев выше, изменив интерфейс, чтобы включить размер и использовать snprintf - i.e.

bool 
foo(const double d, char* const p, const size_t n){
     use snprintf......
     determine if it fit, etc etc etc.
}

Если вам нужен std::string, вам все равно лучше использовать вышеописанное и создать экземпляр строки из результирующего char *, так как будет 2 выделения + 2 выпуска, связанных с решением std:: stringstream, std::string.

BTW Я не могу сказать, является ли "строка" в вопросе std::string или просто общим символом ascii символов "string"

Ответ 6

Лучше всего было бы создать простую темплатную функцию для преобразования любого потокового типа в строку. Вот как я это делаю:

#include <sstream>
#include <string>

template <typename T>
const std::string to_string(const T& data)
{
   std::ostringstream conv;
   conv << data;
   return conv.str();
}

Если вы хотите представление const char *, просто замените conv.str(). c_str() в приведенном выше.

Ответ 7

Я бы сказал, что sprintf является в значительной степени оптимальным способом. Вы можете предпочесть snprintf над ним, но это не имеет особого отношения к производительности.

Ответ 8

Если вы используете работу фрейма Qt4, вы можете пойти:

double d = 5.5;
QString num = QString::number(d);

Ответ 9

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

Он смотрит на баланс между безопасностью, эффективностью, ясностью кода и удобством использования в шаблонах.

Прочтите здесь: http://www.gotw.ca/publications/mill19.htm

Ответ 10

_gcvt или _gcvt_s.

Ответ 11

Это очень полезный поток. Я использую sprintf_s для этого, но я начал сомневаться, что это действительно быстрее, чем другие способы. Я наткнулся на следующий документ на веб-сайте Boost, который показывает сравнение производительности между Printf/scanf, StringStream и Boost.

Double to String - наиболее распространенное преобразование, которое мы делаем в нашем коде, поэтому я буду придерживаться того, что я использовал. Но использование Boost в других сценариях может быть вашим решающим фактором.

http://www.boost.org/doc/libs/1_58_0/doc/html/boost_lexical_cast/performance.html

Ответ 12

В будущем вы можете использовать std::to_chars для написания кода, такого как https://godbolt.org/z/cEO4Sd. К сожалению, только VS2017 и VS2019 поддерживают часть этой функциональности...

#include <iostream>
#include <charconv>
#include <system_error>
#include <string_view>
#include <array>

int main()
{
    std::array<char, 10> chars;
    auto [parsed, error] = std::to_chars(
        chars.data(), 
        chars.data() + chars.size(), 
        static_cast<double>(12345.234)
    );
    std::cout << std::string_view(chars.data(), parsed - chars.data());
}

Для подробного обсуждения деталей MSVC см. Https://www.reddit.com/r/cpp/comments/a2mpaj/how_to_use_the_newest_c_string_conversion/eazo82q/