Зачем так делать
От: FrozenHeart  
Дата: 30.04.14 12:54
Оценка:
Ну вот зачем стримы так делают по умолчанию? Кому это надо?

#include <cmath>
#include <iostream>

int main()
{
    double value = 1.21077;
    std::cout
        << value * std::pow(10.0, 5) << '\n'
        << static_cast<int>(value * std::pow(10.0, 5)) << '\n';
}


Output

121077
121076


Да, все наслышаны об операциях над числами с плавающей точкой, но каждый раз поражаюсь, как сразу несколько особенностей могут "выстрелить" одновременно.
avalon/1.0.434
Re: Зачем так делать
От: Vain Россия google.ru
Дата: 30.04.14 13:04
Оценка: :))
Здравствуйте, FrozenHeart, Вы писали:

FH>Да, все наслышаны об операциях над числами с плавающей точкой, но каждый раз поражаюсь, как сразу несколько особенностей могут "выстрелить" одновременно.

Я вот недавно взял буст filesystem и не смог найти элементарную операцию создания файла. Ненавижу стримы.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: Зачем так делать
От: Хон Гиль Дон Россия  
Дата: 30.04.14 13:12
Оценка:
Здравствуйте, FrozenHeart, Вы писали:

FH>Ну вот зачем стримы так делают по умолчанию? Кому это надо?


FH>
#include <cmath>
FH>#include <iostream>

FH>int main()
FH>{
FH>    double value = 1.21077;
FH>    std::cout
FH>        << value * std::pow(10.0, 5) << '\n'
FH>        << static_cast<int>(value * std::pow(10.0, 5)) << '\n';
FH>}


FH>Output


FH>

121077
FH>121076


FH>Да, все наслышаны об операциях над числами с плавающей точкой, но каждый раз поражаюсь, как сразу несколько особенностей могут "выстрелить" одновременно.


А что не так? Точку не вывело?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[2]: Зачем так делать
От: FrozenHeart  
Дата: 30.04.14 13:43
Оценка:
ХГД> А что не так? Точку не вывело?

То, что на самом деле value * std::pow(10.0, 5) дало в итоге вовсе не 121077, а стрим при этом вывел именно это значение.
avalon/1.0.434
Re[2]: Зачем так делать
От: FrozenHeart  
Дата: 30.04.14 13:44
Оценка:
V> Я вот недавно взял буст filesystem и не смог найти элементарную операцию создания файла. Ненавижу стримы.

Не совсем понял -- это сарказм?
avalon/1.0.434
Re[3]: Зачем так делать
От: Хон Гиль Дон Россия  
Дата: 30.04.14 13:56
Оценка: +1
Здравствуйте, FrozenHeart, Вы писали:

ХГД>> А что не так? Точку не вывело?


FH>То, что на самом деле value * std::pow(10.0, 5) дало в итоге вовсе не 121077, а стрим при этом вывел именно это значение.


Ну так от форматированного вывода люди обычно хотят округления. И он им это округление предоставляет Что стримы, что printf.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[3]: Зачем так делать
От: Vain Россия google.ru
Дата: 30.04.14 14:20
Оценка: +3
Здравствуйте, FrozenHeart, Вы писали:

V>> Я вот недавно взял буст filesystem и не смог найти элементарную операцию создания файла. Ненавижу стримы.

FH>Не совсем понял -- это сарказм?
Нет. Стримы это вообще на любителя. Я не любитель писать все эти << >>, предпочитаю видеть строчку форматирования целиком без всяких << >>.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[2]: Зачем так делать
От: niXman Ниоткуда https://github.com/niXman
Дата: 30.04.14 14:40
Оценка:
Здравствуйте, Vain, Вы писали:

V>Я вот недавно взял буст filesystem и не смог найти элементарную операцию создания файла. Ненавижу стримы.

дизайн стримов конечно ахтунг, и возможности создать файл при помощи boost.filesystem тоже нет, но есть ведь 'std::ofstream file(file_name);'. зачем для этого буст?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[4]: Зачем так делать
От: niXman Ниоткуда https://github.com/niXman
Дата: 30.04.14 14:42
Оценка:
Здравствуйте, Vain, Вы писали:

V>Нет. Стримы это вообще на любителя. Я не любитель писать все эти << >>, предпочитаю видеть строчку форматирования целиком без всяких << >>.

так boost.format же
'file << (boost::format("a=%1%, b=%2%, c=%3%") % a % b % c)'
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: Зачем так делать
От: Кодт Россия  
Дата: 30.04.14 15:29
Оценка:
Здравствуйте, FrozenHeart, Вы писали:

FH>Ну вот зачем стримы так делают по умолчанию? Кому это надо?

Сишный printf
double v = 1.21077;
v *=        100000;
printf("%g %d", v, (int)v); // 121077 121076

сделает то же самое.

А что делать? Выводить там "121077±0.5" или "121076.(9)" ?
Перекуём баги на фичи!
Re: Зачем так делать
От: uzhas Ниоткуда  
Дата: 30.04.14 16:44
Оценка: +1
Здравствуйте, FrozenHeart, Вы писали:

FH>Да, все наслышаны об операциях над числами с плавающей точкой


кроме тебя
Re[5]: Зачем так делать
От: CreatorCray  
Дата: 30.04.14 16:51
Оценка: -1
Здравствуйте, niXman, Вы писали:

X>'file << (boost::format("a=%1%, b=%2%, c=%3%") % a % b % c)'


Я предпочту всё таки стандартный синтаксис: format("a=%u, b=%x, c=%e", a, b, c)
Тем более что на новом стандарте это всё делается красиво, быстро и typesafe.
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[6]: Зачем так делать
От: niXman Ниоткуда https://github.com/niXman
Дата: 30.04.14 17:09
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Я предпочту всё таки стандартный синтаксис: format("a=%u, b=%x, c=%e", a, b, c)

CC>Тем более что на новом стандарте это всё делается красиво, быстро и typesafe.
предпочитай и делай. только не забудь показать, когда сделаешь. а то бустовцы все бьются над typesafe-format`ом, но ничего толкового, юзабильного и соответствующего printf`у не получается. (думаю из-за ненадобности, boost.format делает все необходимое, и даже больше)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[7]: Зачем так делать
От: trophim Россия  
Дата: 30.04.14 19:27
Оценка:
Можно еще попробовать http://fastformat.sourceforge.net/
... << RSDN@Home 1.2.0 alpha 5 rev. 1495>>
Let it be! — Давайте есть пчелу!
Re[7]: Зачем так делать
От: CreatorCray  
Дата: 30.04.14 22:07
Оценка:
Здравствуйте, niXman, Вы писали:

CC>>Я предпочту всё таки стандартный синтаксис: format("a=%u, b=%x, c=%e", a, b, c)

CC>>Тем более что на новом стандарте это всё делается красиво, быстро и typesafe.
X>предпочитай и делай.
Уже сделано давно и используется.

X> только не забудь показать, когда сделаешь.

Весь выкладывать — многабукаф будет.
Вот для затравки header

namespace TypesafeFormat
{
    class TypesafeFormat
    {
    public:
        enum {FORMAT_RESERVE_SIZE = 64};

        TypesafeFormat (const WCHAR* mask, ustring& result) : m_mask (mask ? mask : L""), m_result (result)        {NextParameter ();}

        //////////////////////////////////////////////////////////////////////////
        // Formatters

        //
        // Boolean
        //

        void AddParameter (bool value);

        //
        // Single char
        //

        void AddParameter (char value);
        void AddParameter (WCHAR value);

        //
        // Integers
        //

        void AddParameter (int value);
        void AddParameter (int64 value);
        void AddParameter (long value);

        //
        // Unsigned integers
        //

        void AddParameter (uint value);
        void AddParameter (uint64 value);
        void AddParameter (unsigned long value);

        //
        // Float
        //

        void AddParameter (double value);

        //
        // String
        //

        void AddParameter (const WCHAR* str);
        void AddParameter (const ustring& str);
        void AddParameter (const char* str);
        void AddParameter (const astring& str);

        //
        // Pointer
        //

        void AddParameter (const void* ptr);

        //
        void Finalize ();

    private:

        void NextParameter    ();
        void Reset            ();

        //////////////////////////////////////////////////////////////////////////

        void InvalidFormat    ();
        void FormatAsChar    (WCHAR value);

        //////////////////////////////////////////////////////////////////////////

        const WCHAR* m_mask;
        ustring&    m_result;
        bool        m_readyForParameter;
        WCHAR        m_type;
        FormatCore    m_core;
    };
    
    //////////////////////////////////////////////////////////////////////////
    // Parameters parser

    static void NextParameter (TypesafeFormat& format)
    {
        format.Finalize ();
    }

    template <class VALUE, class... Args> void NextParameter (TypesafeFormat& format, const VALUE& value, const Args&... args)
    {
        format.AddParameter (value);
        NextParameter (format, args...);
    }
}

//////////////////////////////////////////////////////////////////////////
// Public interface

namespace CrayLib
{
    template <class... Args> ustring Format (const WCHAR* mask, const Args&... args)
    {
        ustring result (TypesafeFormat::TypesafeFormat::FORMAT_RESERVE_SIZE);
        TypesafeFormat::TypesafeFormat format (mask, result);
        TypesafeFormat::NextParameter (format, args...);

        return result;
    }

    template <class... Args> void FormatInplace (ustring& output, const WCHAR* mask, const Args&... args)
    {
        output.clear ();
        TypesafeFormat::TypesafeFormat format (mask, output);
        TypesafeFormat::NextParameter (format, args...);
    }

    template <class... Args> void FormatAppend (ustring& output, const WCHAR* mask, const Args&... args)
    {
        TypesafeFormat::TypesafeFormat format (mask, output);
        TypesafeFormat::NextParameter (format, args...);
    }

    template <class... Args> void FormatInplace (size_t reserve, ustring& output, const WCHAR* mask, const Args&... args)
    {
        output.clear ();
        output.reserve (reserve);
        TypesafeFormat::TypesafeFormat format (mask, output);
        TypesafeFormat::NextParameter (format, args...);
    }

    template <class... Args> void FormatAppend (size_t grow, ustring& output, const WCHAR* mask, const Args&... args)
    {
        output.grow (grow);
        TypesafeFormat::TypesafeFormat format (mask, output);
        TypesafeFormat::NextParameter (format, args...);
    }
}


X> а то бустовцы все бьются над typesafe-format`ом, но ничего толкового, юзабильного и соответствующего printf`у не получается.

Печалька. Пусть попросят тех, кто умеет.

X> думаю из-за ненадобности, boost.format делает все необходимое, и даже больше

Думаю что это скорее из-за того что они увязли в backward compatibility.
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[8]: Зачем так делать
От: niXman Ниоткуда https://github.com/niXman
Дата: 01.05.14 01:06
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Весь выкладывать — многабукаф будет.

а какой смысл код прятать?

CC>Вот для затравки header

это же псевдокод =)

CC>Печалька. Пусть попросят тех, кто умеет.

ага, тебя =)

CC>Думаю что это скорее из-за того что они увязли в backward compatibility.

омг %)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[9]: Зачем так делать
От: CreatorCray  
Дата: 01.05.14 03:18
Оценка:
Здравствуйте, niXman, Вы писали:

CC>>Весь выкладывать — многабукаф будет.

X>а какой смысл код прятать?
Его просто много.

CC>>Вот для затравки header

X>это же псевдокод =)
Это кусок реального header
По нему в общем то всё видно как оно работает.

CC>>Печалька. Пусть попросят тех, кто умеет.

X>ага, тебя =)
Не волнуйся, я откажусь.
Мне их coding standard местами не нравится.
Тем не менее, уже давно можно типобезопасно писать print ("...", a, b, c) вместо страхолюдного format ("...") % a % b % c;
Причём сохраняя printf-совместимый синтаксис, чтоб не надо было править сотни строк в готовом коде при портировании.

CC>>Думаю что это скорее из-за того что они увязли в backward compatibility.

X>омг %)
Как ты думаешь, что будет если буст внезапно резко поменяет интерфейс в этой библиотеке?
Что им скажут все те, кому понадобится переписывать все свои вызовы?
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[3]: Зачем так делать
От: breee breee  
Дата: 01.05.14 06:27
Оценка:
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, Vain, Вы писали:


V>>Я вот недавно взял буст filesystem и не смог найти элементарную операцию создания файла. Ненавижу стримы.

X>дизайн стримов конечно ахтунг, и возможности создать файл при помощи boost.filesystem тоже нет, но есть ведь 'std::ofstream file(file_name);'. зачем для этого буст?

А как же boost::filesystem::ofstream file(file_name)?
Re[2]: Зачем так делать
От: FrozenHeart  
Дата: 01.05.14 07:04
Оценка:
К> А что делать? Выводить там "121077±0.5" или "121076.(9)" ?

Почему бы не выводить реальное значение, которым оперирует приложение? Т.е. то же самое, что выведется в случае std::fixed и std::setprecision.
avalon/1.0.434
Re[3]: Зачем так делать
От: rusted Беларусь  
Дата: 01.05.14 07:13
Оценка:
Здравствуйте, FrozenHeart, Вы писали:

К>> А что делать? Выводить там "121077±0.5" или "121076.(9)" ?


FH>Почему бы не выводить реальное значение, которым оперирует приложение? Т.е. то же самое, что выведется в случае std::fixed и std::setprecision.


Большинство реальных значений чисел с плавающей точкой будут иметь очень длинное представление в виде строки в десятичной системе счисления, и при выводе есть всего два варианта — либо округлять либо отбрасывать то, что не влезло. И округление — все же вариант более удобный и создающий меньше проблем.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.