Каков оптимальный способ достижения такого же результата?
void foo(double floatValue, char* stringResult)
{
sprintf(stringResult, "%f", floatValue);
}
Каков оптимальный способ достижения такого же результата?
void foo(double floatValue, char* stringResult)
{
sprintf(stringResult, "%f", floatValue);
}
Я бы, вероятно, пошел с тем, что вы предложили в своем вопросе, так как нет встроенной функции ftoa(), и sprintf дает вам контроль над форматом. Поиск google для "ftoa asm" дает некоторые полезные результаты, но я не уверен, что вы хотите зайти так далеко.
Я уверен, что кто-то скажет boost:: lexical_cast, так что пойдите для этого, если вы используете boost, но это в основном так же, как и в любом случае:
#include <sstream>
#include <string>
std::string doubleToString(double d)
{
std::ostringstream ss;
ss << d;
return ss.str();
}
Обратите внимание, что вы можете легко сделать это в шаблон, который работает на все, что может быть вставлено в поток (а не просто удваивается).
http://www.cplusplus.com/reference/iostream/stringstream/
double d=123.456;
stringstream s;
s << d; // insert d into s
Boost:: lexical_cast < >
В 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"
Лучше всего было бы создать простую темплатную функцию для преобразования любого потокового типа в строку. Вот как я это делаю:
#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() в приведенном выше.
Я бы сказал, что sprintf
является в значительной степени оптимальным способом. Вы можете предпочесть snprintf
над ним, но это не имеет особого отношения к производительности.
Если вы используете работу фрейма Qt4, вы можете пойти:
double d = 5.5;
QString num = QString::number(d);
Трава Саттер провела обширное исследование альтернатив для преобразования int в строку, но я бы подумал, что его аргументы справедливы и для двойника.
Он смотрит на баланс между безопасностью, эффективностью, ясностью кода и удобством использования в шаблонах.
Прочтите здесь: http://www.gotw.ca/publications/mill19.htm
_gcvt
или _gcvt_s
.
Это очень полезный поток. Я использую 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
В будущем вы можете использовать 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/