Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как преобразовать double в строку? 
:(
    Опции темы
TarasProger
Дата 16.8.2015, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 5.8.2015

Репутация: нет
Всего: нет



Как преобразовать double в строку?
PM MAIL   Вверх
feodorv
Дата 16.8.2015, 15:06 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Лучшее из всех решений, на мой взгляд (как ни крути), это всё-таки использование функций семейства printf. В 10-ке MS даже специально поправила вывод форматов для чисел с плавающей точкой, ибо он уступал варианту от UNIX. Другая возможность - написать соответствующую функцию самому, но точность вывода будет уступать (если не применять соответствующие алгоритмы).


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
TarasProger
Дата 16.8.2015, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 5.8.2015

Репутация: нет
Всего: нет



Худшее, а не лучшее. Во-первых чтоб написать, надо долго рыться по справочнику кодов форматирующей строки. Во-вторых ваще не понятно, как задать точность. В-третьих для замены точки на запятую нудо отдельно разбирать результат. Зачем? Можно ведь сразу при разборе числа поставить правильный разделитель. В-четвёртых ваше не понятно, как задать, что до такого то порядка вывод должне быть в формате фиксированной запятой ("31.415"), а с такого то-порядка с плавающей (3.1415*10^18). В-четвёртых не понятно, как поставить "*10^" вместо буквы E. В-пятых она не проверяет буфер. В-шестых буфер надо отдельно приводить к std::wstring. В-седьмых она ещё и уязвима. 
Код
 const static wchar_t      Digitals[10]={L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9'};
              unsigned int Digital;
              std::wstring Result;
              std::wstring Fraction;
              size_t       L;
              size_t       i;
              double Buffer;
 Buffer=floor(abs(Value));
 if (Buffer>=1.0)
 {
  L=(size_t)log10(Buffer)+1;
  if (L<8)
  {
   for (Result=(std::wstring)L"", i=0; Buffer>=1.0; Buffer=floor(Buffer/10.0), ++i)
   {
    Digital=(unsigned int)(modf(Buffer/10.0, nullptr)*10.0);
    Result=Digitals[Digital]+Result;
   }
   Buffer=modf(abs(Value), nullptr);
   for (Fraction=(std::wstring)L","; i<8; Buffer=modf(Buffer*10.0, nullptr), ++i)
   {
    Digital=(unsigned int)(floor(Buffer*10.0));
    Fraction+=Digitals[Digital];
   }
   Result+=Fraction;
  }
 }
. Value равна 2.4, результат "2,3999999". Как от этого избавиться?

Это сообщение отредактировал(а) TarasProger - 16.8.2015, 16:29
PM MAIL   Вверх
feodorv
Дата 16.8.2015, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(TarasProger @  16.8.2015,  16:27 Найти цитируемый пост)
Худшее, а не лучшее.

Дело Ваше. У Вас какая-то патологическая нелюбовь к стандартным решениям, что к стандартной библиотеке, что к printf. Разубеждать Вас не буду.


Цитата(TarasProger @  16.8.2015,  16:27 Найти цитируемый пост)
Value равна 2.4, результат "2,3999999". Как от этого избавиться?

Именно об этом я и говорю:
Цитата(feodorv @  16.8.2015,  15:06 Найти цитируемый пост)
но точность вывода будет уступать (если не применять соответствующие алгоритмы)
Тогда применяйте соответствующие алгоритмы)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
TarasProger
Дата 16.8.2015, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 5.8.2015

Репутация: нет
Всего: нет



Вроде отладил. Но покритикуйте ещё. 
Код
const static wchar_t      Digitals[10]={L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9'};
             unsigned int Digital;
             std::wstring Result;
             std::wstring Fraction;
             std::wstring Exponent;
             size_t       L;
             size_t       i;
             double       Buffer;
if (std::isfinite(Value))
{
 Buffer=abs(Value);
 if ((Buffer+0.00000005)>=1.0)
 {
  Buffer=floor(Buffer)+0.00000005;
  L=(size_t)log10(Buffer)+1;
  if (L<9)
  {
   for (Result=(std::wstring)L"", i=0; Buffer>=1.0; Buffer=floor(Buffer/10.0), ++i)
   {
    Digital=(unsigned int)(modf(Buffer/10.0+0.05, nullptr)*10.0);
    Result=Digitals[Digital]+Result;
   }
   if (L<8)
   {
    Buffer=modf(abs(Value)+0.00000005, nullptr);
    for (Fraction=(std::wstring)L","; i<8; Buffer=modf(Buffer*10.0, nullptr), ++i)
    {
     Digital=(unsigned int)(floor(Buffer*10.0));
     Fraction+=Digitals[Digital];
    }
    Result+=Fraction;
   }
  }
  else
  {
   for (; Buffer>=10.0; Buffer/=10.0);
   Buffer+=0.000000005;
   Digital=(unsigned int)(modf(Buffer/10.0+0.05, nullptr)*10.0);
   Result=Digitals[Digital];
   for (Result+L',', Fraction=(std::wstring)L",", i=1, Buffer=modf(Buffer, nullptr); i<8; Buffer=modf(Buffer*10.0, nullptr), ++i)
   {
    Digital=(unsigned int)(floor(Buffer*10.0));
    Fraction+=Digitals[Digital];
   }
   Result+=Fraction;
   Result+=L"*10^{";
   for (--L, Exponent=L""; L>0; L/=10)
   {
    Digital=(unsigned int)(L%10);
    Exponent=Digitals[Digital]+Exponent;
   }
   Result+=Exponent;
   Result+=L'}';
  }
 }
 else
 {
  if (Value==0.0)
  {
   Result=(std::wstring)L"0.0000000";
  }
  else
  {
   L=(size_t)(ceil(-log10(Buffer)));
   for (i=0; i<L; ++i)
   {
    Buffer*=10.0;
   }
   Buffer+=0.000000005;
   Digital=(unsigned int)(modf(Buffer/10.0+0.05, nullptr)*10.0);
   Result=Digitals[Digital];
   for (Result+L',', Fraction=(std::wstring)L",", i=1, Buffer=modf(Buffer, nullptr); i<8; Buffer=modf(Buffer*10.0, nullptr), ++i)
   {
    Digital=(unsigned int)(floor(Buffer*10.0));
    Fraction+=Digitals[Digital];
   }
   Result+=Fraction;
   Result+=L"*10^{-";
   for (Exponent=L""; L>0; L/=10)
   {
    Digital=(unsigned int)(L%10);
    Exponent=Digitals[Digital]+Exponent;
   }
   Result+=Exponent;
   Result+=L'}';
  }
 }
 if (Value<0.0)
 {
  Result=L'-'+Result;
 }
 Result+=L' ';
 Result+=(std::wstring)(*Unit);
}
else
{
 if (std::isnan(Value))
 {
  Result=L"Значение не определено";
 }
 else
 {
  if (Value>0.0)
  {
   Result=L"∞";
  }
  else
  {
   Result=L"-∞";
  }
 }
}
return Result;
. Есть ли где глюки? Тормоза?

Добавлено через 2 минуты и 25 секунд
Цитата(feodorv @  16.8.2015,  17:03 Найти цитируемый пост)
Дело Ваше. У Вас какая-то патологическая нелюбовь к стандартным решениям, что к стандартной библиотеке, что к printf. Разубеждать Вас не буду.
До стандартной библиотеки я просто ещё не добрался. А printf не люблю не только я. И она не стандартная, а устаревшая.


Это сообщение отредактировал(а) TarasProger - 16.8.2015, 19:28
PM MAIL   Вверх
disputant
Дата 16.8.2015, 21:36 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 28.11.2011

Репутация: нет
Всего: 3



Цитата(feodorv @ 16.8.2015,  15:06)
Лучшее из всех решений, на мой взгляд (как ни крути), это всё-таки использование функций семейства printf.

Страуструп советует использовать вывод в stringstream, кстати...
PM MAIL   Вверх
feodorv
Дата 16.8.2015, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Уж лучше использовать _ecvt_s smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
TarasProger
Дата 17.8.2015, 07:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 5.8.2015

Репутация: нет
Всего: нет



Цитата(feodorv @  16.8.2015,  21:39 Найти цитируемый пост)
Уж лучше использовать _ecvt_s
И чем же оно лучше стандартного решения? ООП-ного, надёжного и безопасного.

Добавлено @ 07:47
disputant, а как задать точность преобразования и заставить его выводить не значащие ноли в конце? 
Код
  Buffer.precision(8);
  Buffer<<Value;
  Buffer<<L' ';
  Buffer>>Result;
  return Result;
 не помогает.   Buffer.precision(2);
  Buffer<<Value;
  Buffer<<L' ';
  Buffer>>Result;
  return Result;[/code] точность ограничивает, Value=3.14, результат 3.1, но Buffer.precision(8);
  Buffer<<Value;
  Buffer<<L' ';
  Buffer>>Result;
  return Result;[/code] выводит 3.14 вместо 3.1400000. Как задать разделитель целой и дробной части?

Это сообщение отредактировал(а) TarasProger - 17.8.2015, 07:56
PM MAIL   Вверх
feodorv
Дата 17.8.2015, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(TarasProger @  17.8.2015,  07:33 Найти цитируемый пост)
И чем же оно лучше стандартного решения?

Тем, что не использует никаких стандартных решений smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Курсант
Дата 17.8.2015, 16:22 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 338
Регистрация: 21.2.2009
Где: Балашиха или Воро неж

Репутация: нет
Всего: 4



Цитата(TarasProger @ 17.8.2015,  07:33)
Цитата(feodorv @  16.8.2015,  21:39 Найти цитируемый пост)
Уж лучше использовать _ecvt_s
И чем же оно лучше стандартного решения? ООП-ного, надёжного и безопасного.

Добавлено @ 07:47
disputant, а как задать точность преобразования и заставить его выводить не значащие ноли в конце? 
Код
  Buffer.precision(8);
  Buffer<<Value;
  Buffer<<L' ';
  Buffer>>Result;
  return Result;
 не помогает.   Buffer.precision(2);
  Buffer<<Value;
  Buffer<<L' ';
  Buffer>>Result;
  return Result;[/code] точность ограничивает, Value=3.14, результат 3.1, но Buffer.precision(8);
  Buffer<<Value;
  Buffer<<L' ';
  Buffer>>Result;
  return Result;[/code] выводит 3.14 вместо 3.1400000. Как задать разделитель целой и дробной части?

Уважаемый TarasProger, мне очень нравится Ваш стиль программирования, в нём чувствуется будущий хороший специалист. Хотя и заметно, что программирование является для Вас чем-то новым, Вы отлично улавливаете суть, у Вас есть творческая струнка, которая звенит, и это здорово. Но...

Примите к сведению, что сейчас у Вас необходимый этап развития - изобретение велосипедов на квадратных колёсах. Хотя колёса у Ваших велосипедов не такие уж и квадратные. На мой взгляд, это лучше, чем бездумное использование чужих решений. Главное - не перегнуть палку в этом вопросе, изучать стандартные решения, использовать их. Если разные библиотеки типа Qt или WxWidgets - это ещё спорный момент, то такие вещи как STL (стандартная библиотека шаблонов С++), WinAPI (не уверен что злободневно) и .NET - это то, чем нужно пользоваться. Это системы с очень изящной структурой, даже поверхностное знакомство с ними учит организовывать работу сложных программ.

То есть те ответы, которые Вам дают - они отличные, если говорить строго технически. Есть отличный принцип в конструировании - меньше изобретать и больше конструировать. Нужно стараться максимально агрегатировать уже написанные функции из стандартных библиотек. Они, во-первых, избавлены от ошибок многочисленными прогонами и частым использованием, во-вторых, экономят время при разработке ПО, в третьих, упрощают поддержку Ваших программ другими разработчиками, которые знакомы со стандартными решениями, и не знакомы с Вашими решениями.

НО, повторюсь, то, что Вы делаете, т.е. изобретение своих библиотек - это, на мой взгляд, необходимый этап. Более того, уверен, большая часть людей, рекомендующих Вам использовать стандартные решения, сама прошла через такое вот изобретение велосипедов. Неважно в каком возрасте. Это позволяет отточить алгоритмическое мышление.

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

Пишите ещё!
PM ICQ Skype   Вверх
volatile
Дата 17.8.2015, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(Курсант @  17.8.2015,  16:22 Найти цитируемый пост)
необходимый этап развития - изобретение велосипедов на квадратных колёсах.

Да всё замечательно, если бы только он не внушал "городу и миру", что только велосипеды с квадратными колесами являются правильными.

PM MAIL   Вверх
volatile
Дата 17.8.2015, 21:06 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Насчет использования принтф с C++, да оно конечно не вписывается в стройную систему C++ никаким боком.
И Страуструп конечно будет советовать против.
Но...
по удобству использования и эффективности полученного кода, она даст мноооого очков вперед форы выводу в stringstream и иже с ними.

Ну а вообще это холивар...

PM MAIL   Вверх
Alexeis
Дата 18.8.2015, 01:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



Цитата(volatile @  17.8.2015,  22:06 Найти цитируемый пост)
по удобству использования и эффективности полученного кода, она даст мноооого очков вперед форы выводу в stringstream и иже с ними.

  Поэтому добрые люди изобрели lexical_cast<> чтобы упростить эту конструкцию. Хотя я против использования кучи в таких тривиальных задачах.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
disputant
Дата 19.8.2015, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 28.11.2011

Репутация: нет
Всего: 3



Цитата(TarasProger @ 17.8.2015,  07:33)
disputant, а как задать точность преобразования и заставить его выводить не значащие ноли в конце? 

Ну это же поток, так что <iomanip> вам в помощь!...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.3192 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.