Здравствуйте, Аноним, Вы писали:
А>|Privet all. А>||Kak preobrozovat char[] v float, to est esli imeem float 0.4 poluchit char[] "0.4". А>\Spasibo
см. ф-ю _gcvt (расширение RunTime библиотеки от Microsoft)
либо sprintf(buf, "%f", mfloat)
В искустве летать есть один маленький секрет. Секрет этот в том,чтобы бросить себя изо всех сил на землю — и не попасть. Выберете погожий денек и попробуйте сами.
Здравствуйте, alexkro, Вы писали:
A>Здравствуйте, Кодт, Вы писали:
К>>Здравствуйте, Alxndr, Вы писали:
A>>>Смотри в сторону boost::lexical_cast
К>>Будьте проще, и люди потянутся. К>>
К>>char buf[32]; // вроде должно хватить
К>>sprintf(buf, "%g", 1.23); // %g - выбирать наиболее подходящую запись: 0.123e+0001 или 1.23
К>>
A>Что может быть проще: A>
A>string str = boost::lexical_cast<string>( 1.23 );
A>
A>А если с буферами тягаться, то недолго и гемор ввиде security holes получить.
Да уж куда проще -- ездить из Москвы в Питер через Вашингтон.
typedef num_put<_Elem, _Iter> _Nput;
_Myt& operator<<(double _Val)
{ // insert a double
ios_base::iostate _State = ios_base::goodbit;
const sentry _Ok(*this);
if (_Ok)
{ // state okay, use facet to insertconst _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput);
_TRY_IO_BEGIN
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this,
_Myios::fill(), _Val).failed())
_State |= ios_base::badbit;
_CATCH_IO_END
}
_Myios::setstate(_State);
return (*this);
}
Пересадка четвертая. std::num_put -> sprintf
_OutIt put(_OutIt _Dest,
ios_base& _Iosbase, _Elem _Fill, double _Val) const
{ // put formatted double to _Destreturn (do_put(_Dest, _Iosbase, _Fill, _Val));
}
_VIRTUAL _OutIt do_put(_OutIt _Dest,
ios_base& _Iosbase, _Elem _Fill, double _Val) const
{ // put formatted double to _Destchar _Buf[_MAX_EXP_DIG + _MAX_SIG_DIG + 64], _Fmt[8];
streamsize _Precision = _Iosbase.precision() <= 0
&& !(_Iosbase.flags() & ios_base::fixed)
? 6 : _Iosbase.precision(); // desired precisionint _Significance = _MAX_SIG_DIG < _Precision
? _MAX_SIG_DIG : (int)_Precision; // actual sprintf precision
_Precision -= _Significance;
size_t _Beforepoint = 0; // zeros to add before decimal point
size_t _Afterpoint = 0; // zeros to add after decimal pointif ((_Iosbase.flags() & ios_base::floatfield) == ios_base::fixed)
{ // scale silly fixed-point valuebool _Signed = _Val < 0;
if (_Signed)
_Val = -_Val;
for (; 1e35 <= _Val && _Beforepoint < 5000; _Beforepoint += 10)
_Val /= 1e10; // drop 10 zeros before decimal pointif (0 < _Val)
for (; 10 <= _Precision && _Val <= 1e-35
&& _Afterpoint < 5000; _Afterpoint += 10)
{ // drop 10 zeros after decimal point
_Val *= 1e10;
_Precision -= 10;
}
if (_Signed)
_Val = -_Val;
}
return (_Fput(_Dest, _Iosbase, _Fill, _Buf,
_Beforepoint, _Afterpoint, _Precision,
::sprintf(_Buf, _Ffmt(_Fmt, 0, _Iosbase.flags()),
_Significance, _Val))); // convert and put
}
Обратите внимание, как изящно, на лету формируется строка формата для передачи в sprintf.
Маршрут ещё не закончен. В его конце вы наёдёте _fcvt, _gcvt или что-то подобное. А в самых потрохах -- кусок на ассемблере, который и делает реальную работу.
И последнее:
Не надо путать программирование и идиотию. Авторы boost а, во всяком случае этой его части, программистами названы быть не могут. Ими вообще должны заниматься специальные люди в былых халатах.
Здравствуйте, Шахтер, Вы писали:
Ш>Да уж куда проще -- ездить из Москвы в Питер через Вашингтон.
Тут скорее другая аналогия, когда я звоню из Москвы в Питер, мне до лампочки как идет сигнал, хоть через Куала Лумпур (что вполне возможно).
Если знаешь чем плох lexical_cast, и как его можно исправить, и это действительно критично, люди работающие над boost всегда готовы выслушать дельные предложения.
А пугать людей магическими цифрами типа 32 (в char buf[32]) это хорошо? Почему 32, а не 128 или 13?
Но это больше к философии. Извинте, если что не так.
Hello, Шахтер!
You wrote on Fri, 19 Mar 2004 01:41:21 GMT:
Ш> Да уж куда проще -- ездить из Москвы в Питер через Вашингтон.
Ш> Пересадка первая. lexical_cast -> detail::lexical_stream Ш>...
Да уж, постарались ребята, так постарались . Меня мучает вот такой вопрос: если бы программисты, писавшие boost::lexical_cast сделали его попроще, смог бы он попасть в библиотеку boost ?
Здравствуйте, ArtDenis, Вы писали:
AD>Да уж, постарались ребята, так постарались . Меня мучает вот такой вопрос: если бы программисты, писавшие boost::lexical_cast сделали его попроще, смог бы он попасть в библиотеку boost ?
Честно скажу, я не разбирался в деталях. Но, если есть реализация попроще, скорее всего попала бы в boost (why not?). Только сначала в черновики, потом бы выяснилось что она на некоторых платформах или с некоторыми вариантами опций компилятора не работает, или работает не корректно. Пришлось бы изменить код, подправить, и скорее всего, через некоторое время, получили бы такой же по сложности код То что там такое нагромождение, этому наверняка есть какое то обоснование. Возможно, учитываеться многопоточноснь, обработка исключений, отладочные функции, разрядность, ошибки и нюансы разных компиляторов и библиотек (обхода таких "нюансов" хватает в boost), и т.п.. В отличии от Шахтера, я не думаю что boost пишут не программисты.
IMHO, Основная идея boost ведь не в том что бы внутри код был предельно простым, а что бы этой библиотекой можно было пользовать на разных платформах, не переписывая по сто раз велосипеды, например, того же преобразования вещественного числа в строку.
Здравствуйте, ArtDenis, Вы писали:
AD>Hello, Шахтер! AD>You wrote on Fri, 19 Mar 2004 01:41:21 GMT:
Ш>> Да уж куда проще -- ездить из Москвы в Питер через Вашингтон.
Ш>> Пересадка первая. lexical_cast -> detail::lexical_stream Ш>>...
AD>Да уж, постарались ребята, так постарались . Меня мучает вот такой вопрос: если бы программисты, писавшие boost::lexical_cast сделали его попроще, смог бы он попасть в библиотеку boost ?
Hello, sergey_shandar!
You wrote on Fri, 19 Mar 2004 05:10:00 GMT:
ss> IMHO, Основная идея boost ведь не в том что бы внутри код был предельно ss> простым, а что бы этой библиотекой можно было пользовать на разных ss> платформах, не переписывая по сто раз велосипеды, например, того же ss> преобразования вещественного числа в строку.
Да, ладно, я же просто пошутил. А если говорить серьёзно, то мне не понятно, почему в C++ и C нет средства для преобразования чисел в строковое представление, которое бы удовлетворяло следующим условиям:
1. Безопасность и надёжность
2. Выбор формата чисел
3. Высокая скорость
4. Маленький объём кода
Если построить таблицу по функциям переводящим double -> text и по вышеприведённым условиям, то получим:
Здравствуйте, sergey_shandar, Вы писали:
_>Здравствуйте, Шахтер, Вы писали:
Ш>>Да уж куда проще -- ездить из Москвы в Питер через Вашингтон.
_>Тут скорее другая аналогия, когда я звоню из Москвы в Питер, мне до лампочки как идет сигнал, хоть через Куала Лумпур (что вполне возможно).
Если у тебя задержка сигнала будет 10 секунд, разговаривать нормально ты не сможешь.
_>Если знаешь чем плох lexical_cast, и как его можно исправить, и это действительно критично, люди работающие над boost всегда готовы выслушать дельные предложения.
Скажем так, я не работаю бесплатно.
_>А пугать людей магическими цифрами типа 32 (в char buf[32]) это хорошо?
Вот это пугало зарыто в недрах stl: _MAX_EXP_DIG + _MAX_SIG_DIG + 64.
_>Почему 32, а не 128 или 13?
Баг стандарта. Приходится исправлять вручную. Сильно умные небожители, пишущие стандарт, никак не могут заметиь простых человеческих нужд -- а именно примитивов преобразования фундаментальных типов в строку ( типа itoa , _gcvt и.т.п. ). Вот в соответствующем заголовке и должны быть представлены соответствующие константы для размеров буферов. Написать соответсвующиё хидер -- делов на 10 минут. Рассмотреть и утвердить это в комитете не могут уже много лет. Очевидно, у ключевых членов комитета, большие задержки в сигнальных цепях в голове.
_>Но это больше к философии. Извинте, если что не так.
Это не философия, а практика. Если я в своей работе буду применять такие тормознутые средства, то у тебя действительно задержка сигнала от Москвы до Питера будет 10 секунд.
Здравствуйте, c-smile, Вы писали:
CS>И последнее: судя по уровню человека задающего вопрос ему только буста и не хватает для полного щастья.
Тогда уж скорее ему не хватает вот этого, для полного примера :
CS>In total, depending on the implementation, buffer should be between 8 and 9 characters larger than num to contain any possible result. CS>http://www.cplusplus.com/ref/cstdlib/gcvt.html
И еще два параграфа по подсчету еще одного магического числа 'num'.
Вот именно, исходя из того, что человеку просто нужно преобразовать число в строку, boost ему и не хватает. Хотя я ничего против других вариантов не имею. Пусть выбирает. Причем, скорее всего, он/она выберет вариант Кодта.
Здравствуйте, Шахтер, Вы писали:
Ш>Вот это пугало зарыто в недрах stl: _MAX_EXP_DIG + _MAX_SIG_DIG + 64. Ш>Баг стандарта. Приходится исправлять вручную. ...
Если так, то зачем тогда советовать людям то что проблематично использовать?
Ш>Это не философия, а практика. Если я в своей работе буду применять такие тормознутые средства..., то у тебя действительно задержка сигнала от Москвы до Питера будет 10 секунд.
А он может СМС посылает (опять аналогии , я не видел что бы в вопросе были слова сверх быстрое преобразования числа в строку.
Многие приложения на Java работают, и ниче, не тормозят, даже на мобильных телефонах. А когда тормозят то те функции которые тормозят и переписываються.
Здравствуйте, ArtDenis, Вы писали:
AD>Да, ладно, я же просто пошутил. А если говорить серьёзно, то мне не понятно, почему в C++ и C нет средства для преобразования чисел в строковое представление, которое бы удовлетворяло следующим условиям:
AD>1. Безопасность и надёжность AD>2. Выбор формата чисел AD>3. Высокая скорость AD>4. Маленький объём кода
AD>Если построить таблицу по функциям переводящим double -> text и по вышеприведённым условиям, то получим:
AD>
AD>Как видно, четырёх плюсов подряд нигде не наблюдаеся
Я тоже как-то думал над этим. И тоже пришел к выводу что в стандартных C/C++ нет удобного способа пребразования значения в строковое представление. А альтернативные удобные способы достаточно дорогие.
Мне хочется иметь набор перегруженных шаблонов функций, возвращающих итератор на конец строкового представления, конечно же без зачастую ненужного нуль-терминирования. Все параметры форматирования должны паковаться в спец тип вместе с форматируемым значением.
Типа такого на примере signed/unsigned int и дополнительного шестнацатиричного формата:
// шестнадцатиричный форматтер - может использоваться с любыми семантически подходящими типамиtemplate<typename T>
struct hex_t
{
T value;
explicit hex_t(T val): value(val) {}
};
template<typename T>
hex_t<T> hex(T const& val) { return hex_t<T>(val); }
// объявления шаблонов преобразования
tempalte<typename OutIt>
OutIt stringize(OutIt it, unsigned x);
tempalte<typename OutIt>
OutIt stringize(OutIt it, signed x);
tempalte<typename OutIt>
OutIt stringize(OutIt it, hex_t<unsigned> x);
tempalte<typename OutIt>
OutIt stringize(OutIt it, hex_t<signed> x);
// здесь мы несколько выбиваемся из стиля, но должнен же быть шаблон для удобной работы с массивом символов,
// терминирующий нулем и возвращающий указатель на НАЧАЛО массиваtemplate<typename Char, typename T>
Char* stringize_to_array(Char* buf, T const& x)
{
*stringize(buf, x) = 0;
return buf;
}
Такие шаблоны было бы весьма удобно использовать в различных ситуациях. Вот напридумывал примеры использования:
Здравствуйте, Шахтер, Вы писали:
Ш>Не надо путать программирование и идиотию. Авторы boost а, во всяком случае этой его части, программистами названы быть не могут. Ими вообще должны заниматься специальные люди в былых халатах.
Кстати велика вероятность, что boost::lexical_cast будет в C++0x. Так что привыкай.