Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 09.09.09 22:33
Оценка: 4 (1) +1
Robert C. Martin's Clean Code Tip #12: Eliminate Boolean Arguments
http://www.informit.com/articles/article.aspx?p=1392524
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Смерть булевским аргументам!
От: K13 http://akvis.com
Дата: 10.09.09 03:21
Оценка:
J>Robert C. Martin's Clean Code Tip #12: Eliminate Boolean Arguments
J>http://www.informit.com/articles/article.aspx?p=1392524

В случае единственного параметра bool никуда девать не надо.
set_visible( true );

А так — согласен, enum гораздо понятнее.
Re[2]: Смерть булевским аргументам!
От: IT Россия linq2db.com
Дата: 10.09.09 03:23
Оценка: 1 (1) +2
Здравствуйте, K13, Вы писали:

K13>А так — согласен, enum гораздо понятнее.


Или именованные параметры.
Если нам не помогут, то мы тоже никого не пощадим.
Re: Смерть булевским аргументам!
От: wallaby  
Дата: 10.09.09 04:24
Оценка: 1 (1) +4
Здравствуйте, jazzer, Вы писали:

J>Robert C. Martin's Clean Code Tip #12: Eliminate Boolean Arguments

J>http://www.informit.com/articles/article.aspx?p=1392524

Так много слов для одной простой мысли:
Вместо одной функции с булевым аргументом часто правильнее использовать две функции.
---
The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true
Re: Смерть булевским аргументам!
От: igna Россия  
Дата: 10.09.09 04:41
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Robert C. Martin's Clean Code Tip #12: Eliminate Boolean Arguments

J>http://www.informit.com/articles/article.aspx?p=1392524

В рассматриваемом случае и при использовании языка, позволяющего определять свои типы, не уступающие по эффективности встроенным, можно было бы просто определить типы degree и radian, и тогда можно было бы и булевый параметр убрать, и метод/функцию переименовывать не пришлось бы.

Все в сослагательном наклонении, потому-что конкретная проблема надумана, аргумент конечно же должен задаваться в радианах. Кому нужно, пусть преобразовывает градусы в радианы перед вызовом, например так:

    int status = controlRod.rotate(fromDegree(30))


Хотя на Java скорее нужно будет дополнительно указать имя класса, зато код станет законченно объектно-ориентированным :

    int status = controlRod.rotate(AngleConversion.fromDegree(30))


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

PS. Этот автор у тебя тоже в числе экспертов?
Re[2]: Смерть булевским аргументам!
От: igna Россия  
Дата: 10.09.09 04:45
Оценка:
Здравствуйте, wallaby, Вы писали:

W>Так много слов для одной простой мысли:


Согласен, там словоблудие. И ведь приходится читать, чтобы убедиться, что автор не спрятал хоть какую-нибудь полувменяемую мыслишку среди строк. Но не спрятал.
Re[2]: Смерть булевским аргументам!
От: Константин Б. Россия  
Дата: 10.09.09 09:02
Оценка:
Здравствуйте, wallaby, Вы писали:

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


J>>Robert C. Martin's Clean Code Tip #12: Eliminate Boolean Arguments

J>>http://www.informit.com/articles/article.aspx?p=1392524

W>Так много слов для одной простой мысли:

W>Вместо одной функции с булевым аргументом часто правильнее использовать две функции.

Или например:
Вместо magic number'ов правильнее использовать именованые константы или енумы.

Кому как больше нравится
Re[3]: Смерть булевским аргументам!
От: Flying Dutchman Украина  
Дата: 10.09.09 09:09
Оценка: +1
Здравствуйте, IT, Вы писали:

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


K13>>А так — согласен, enum гораздо понятнее.


IT>Или именованные параметры.


Еще можно использовать константы, примерно так:

  const bool Radians = true;
  ...
  int status = fuelRod.rotate(0.5, Radians);


Я как-то учавствовал в проекте, в котором все числа, строки и т.д. должны были предварительно определены как константы (за исключением чисел 0 и 1). Очень разумное правило.
Re[2]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 10.09.09 09:38
Оценка:
Здравствуйте, wallaby, Вы писали:

W>Так много слов для одной простой мысли:

W>Вместо одной функции с булевым аргументом часто правильнее использовать две функции.
+1

ну так одну простую мысль в голом виде высказывать бесполезно, ее уже все высказали по многу раз
А тут — наглядный пример.

В качестве иллюстрации для начинающих программеров — самое оно.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Смерть булевским аргументам!
От: igna Россия  
Дата: 10.09.09 09:39
Оценка:
Здравствуйте, Flying Dutchman, Вы писали:

FD>Еще можно использовать константы, примерно так:


FD>  const bool Radians = true;
FD>  ...
FD>  int status = fuelRod.rotate(0.5, Radians);


Так у него true то радианы, то градусы означает:

    int status = controlRod.rotate(30, Radians); // Здесь твоя константа Radians означает градусы
Re[2]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 10.09.09 09:47
Оценка: +1
Здравствуйте, igna, Вы писали:

I>В рассматриваемом случае и при использовании языка, позволяющего определять свои типы, не уступающие по эффективности встроенным, можно было бы просто определить типы degree и radian, и тогда можно было бы и булевый параметр убрать, и метод/функцию переименовывать не пришлось бы.

+1

I>Все в сослагательном наклонении, потому-что конкретная проблема надумана, аргумент конечно же должен задаваться в радианах.

Можете выбрать любой цвет, при условии что вы выбираете черный
Не все так однозначно.
Градусы хороши своей целочисленностью.

I>Возможно стоит добавить, что это преобразование нужно выполнять только при вводе информации от пользователя, внутри программа должна иметь дело только с радианами.

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

I>PS. Этот автор у тебя тоже в числе экспертов?

Я *там* в качестве эксперта упоминал Глассборо — есть сомнения, что он эксперт? Тот, кого ты *там* нашел, я впервые увидел. Ладно, здесь это офтопик в любом случае.
А эта конкретная статья в RSS прилетела, посмеялся, пока читал, решил сюда запостить.
Надеюсь, что вы тоже посмеялись.

С другой стороны, хоть и смешно, но проблема реальная: во многих признанных API (в винде, например) булевские переменные летают только в путь, в результате смотришь в вызов функции с пятью true, как дурак, и пытаешься понять, что же они все означают.
Так что мысль вроде как и очевидна, да, видать, лень побеждает — bool же проще сунуть, чем целое перечисление объявлять или вообще специальный полноценный тип ваять.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Смерть булевским аргументам!
От: igna Россия  
Дата: 10.09.09 10:04
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Градусы хороши своей целочисленностью.


Ась? Полградуса тоже бывают.

J>То же, кстати, относится к доброй половине финансовых программ, где цены, вроде как, не целые, но из лучше хранить как целые или как пару целых.


Относится, но не тоже.

J>С другой стороны, хоть и смешно, но проблема реальная: во многих признанных API (в винде, например) булевские переменные летают только в путь, в результате смотришь в вызов функции с пятью true, как дурак, и пытаешься понять, что же они все означают.

J>Так что мысль вроде как и очевидна, да, видать, лень побеждает — bool же проще сунуть, чем целое перечисление объявлять или вообще специальный полноценный тип ваять.

IMHO в Windows API проблема другая, многие функции этого API выполняет несколько эээ ... функций, отсюда и неприятности. А сами по себе булевые параметры ничуть не хуже, к примеру, параметров целых; и те, и другие можно перепутать. Но сторонников определять типы вроде XCoordinate, YCoordinate, XDistance и YDistance, которые нельзя просто по ошибке использовать друг вместо друга, немного.
Re[3]: По поводу финансовых программ
От: igna Россия  
Дата: 10.09.09 10:08
Оценка:
Здравствуйте, jazzer, Вы писали:

J>То же, кстати, относится к доброй половине финансовых программ, где цены, вроде как, не целые, но из лучше хранить как целые или как пару целых.


Кстати, а что, все же есть финансовые программы, которые хранят цены как float? Никогда подобными вещами не занимался, но вроде это расхожий пример неправильного выбора типа.
Re: Смерть булевским аргументам!
От: Pavel Dvorkin Россия  
Дата: 10.09.09 10:52
Оценка: -1
Здравствуйте, jazzer, Вы писали:

J>Robert C. Martin's Clean Code Tip #12: Eliminate Boolean Arguments

J>http://www.informit.com/articles/article.aspx?p=1392524

Кое-что по существу верно, но вообще — проблема ИМХО не стоит выеденного яйца. Пустяками заниматься изволим
With best regards
Pavel Dvorkin
Re[4]: По поводу финансовых программ
От: jazzer Россия Skype: enerjazzer
Дата: 10.09.09 10:58
Оценка:
Здравствуйте, igna, Вы писали:

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


J>>То же, кстати, относится к доброй половине финансовых программ, где цены, вроде как, не целые, но из лучше хранить как целые или как пару целых.


I>Кстати, а что, все же есть финансовые программы, которые хранят цены как float? Никогда подобными вещами не занимался, но вроде это расхожий пример неправильного выбора типа.


Есть, конечно.
Зависит от задачи.
Финансовые программы очень разные бывают.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Смерть булевским аргументам!
От: Pro100Oleh Украина  
Дата: 10.09.09 12:50
Оценка:
В чем прелесть bool — в том что он гарантированно может хранить лишь два значения, отчего код по анализу параметра будет проще:

        public void TestBool(bool arg)
        {
            if (arg)
            {
                Console.WriteLine("first situation");
            }
            else
            {
                Console.WriteLine("second situation");
            }
        }

        public enum MyEnum
        {
            FirstSituation,
            SecondSituation
        }

        public void TestEnum(MyEnum situation)
        {
            switch (situation)
            {
                case MyEnum.FirstSituation:
                    Console.WriteLine("first situation");
                    break;
                case MyEnum.SecondSituation:
                    Console.WriteLine("second situation");
                    break;
                default:
                    throw new Exception("Unknown situation");
            }
        }
Pro
Re[2]: Смерть булевским аргументам!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.09.09 13:20
Оценка: :)
Здравствуйте, Pro100Oleh, Вы писали:

PO>В чем прелесть bool — в том что он гарантированно может хранить лишь два значения, отчего код по анализу параметра будет проще:


нет такой гарантии
static unsafe void Main(string[] args)
{
    int x = 0x03;
    bool b = *(bool*)(void*)(&x);
    Console.WriteLine(*(int*)(void*)(&b)); // 3

    Console.WriteLine(b == false);         // False
    bool b2 = true;
    Console.WriteLine(b == b2);            // False
}

Недавно эта тема обсасывалась на rsdn.
Re[3]: Смерть булевским аргументам!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.09.09 13:29
Оценка:
Здравствуйте, samius, Вы писали:

S>нет такой гарантии

S>Недавно эта тема обсасывалась на rsdn.
здесь
Автор: Пельмешко
Дата: 20.07.09
Re[5]: Смерть булевским аргументам!
От: Flying Dutchman Украина  
Дата: 10.09.09 14:17
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Flying Dutchman, Вы писали:


FD>>Еще можно использовать константы, примерно так:


I>
FD>>  const bool Radians = true;
FD>>  ...
FD>>  int status = fuelRod.rotate(0.5, Radians);
I>


I>Так у него true то радианы, то градусы означает:


I>
I>    int status = controlRod.rotate(30, Radians); // Здесь твоя константа Radians означает градусы
I>


Да, тяжелый случай. По-хорошему надо код отрефакторить, а пока этого не сделано, завести две константы: FuelRadians и ControlRadians.
Re[4]: Смерть булевским аргументам!
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 10.09.09 15:49
Оценка:
Здравствуйте, Flying Dutchman, Вы писали:

FD>Еще можно использовать константы, примерно так:


FD>
FD>  const bool Radians = true;
FD>  ...
FD>  int status = fuelRod.rotate(0.5, Radians);
FD>


Имхо, лучше так:

const bool Radians = true;
...
int status = fuelRod.rotate(0.5 * ONE_RADIAN);
Re[3]: Смерть булевским аргументам!
От: Кодт Россия  
Дата: 10.09.09 16:46
Оценка: 1 (1) +1
Здравствуйте, samius, Вы писали:

PO>>В чем прелесть bool — в том что он гарантированно может хранить лишь два значения, отчего код по анализу параметра будет проще:

S>нет такой гарантии

Это неопределённое поведение, ничем не лучше любого другого забега по памяти. При чём здесь bool?
Перекуём баги на фичи!
Re[4]: Смерть булевским аргументам!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.09.09 16:51
Оценка:
Здравствуйте, Кодт, Вы писали:

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


PO>>>В чем прелесть bool — в том что он гарантированно может хранить лишь два значения, отчего код по анализу параметра будет проще:

S>>нет такой гарантии

К>Это неопределённое поведение, ничем не лучше любого другого забега по памяти. При чём здесь bool?

Я прикополся к выделенному в контексте сравнения bool с enum. Разница между ними лишь в том, что в bool сложнее засунуть что-то левое, но как и enum он может хранить левые значения.
Re[5]: Смерть булевским аргументам!
От: nikov США http://www.linkedin.com/in/nikov
Дата: 10.09.09 17:01
Оценка:
Здравствуйте, samius, Вы писали:

К>>Это неопределённое поведение, ничем не лучше любого другого забега по памяти. При чём здесь bool?

S>Я прикополся к выделенному в контексте сравнения bool с enum. Разница между ними лишь в том, что в bool сложнее засунуть что-то левое, но как и enum он может хранить левые значения.

Всё-таки разница здесь не количественная (проще-сложнее), а качественная. Формально, с точки зрения языка, bool не может содержать других значений.

4.1.8 The bool type
The bool type represents boolean logical quantities. The possible values of type bool are true and false.

4.1.9 Enumeration types
An enumeration type is a distinct type with named constants. Every enumeration type has an underlying type, which must be byte, sbyte, short, ushort, int, uint, long or ulong. The set of values of the enumeration type is the same as the set of values of the underlying type.


Но код, имеющий соответствующие привилегии, может наружить этот инвариант среды выполнения. Это же можно сделать, если залезть в процессор с паяльником.
Re[5]: Смерть булевским аргументам!
От: dotneter  
Дата: 10.09.09 17:36
Оценка: 30 (1)
Здравствуйте, Mystic, Вы писали:

Или так
[<Measure>] type Radian
int status = fuelRod.rotate(0.5<Radian>);
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Talk is cheap. Show me the code.
Re[6]: Смерть булевским аргументам!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.09.09 17:48
Оценка: 21 (2)
Здравствуйте, nikov, Вы писали:

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


S>>Я прикополся к выделенному в контексте сравнения bool с enum. Разница между ними лишь в том, что в bool сложнее засунуть что-то левое, но как и enum он может хранить левые значения.


N>Всё-таки разница здесь не количественная (проще-сложнее), а качественная. Формально, с точки зрения языка, bool не может содержать других значений.

Да, формально с точки зрения языка не может, но рассчитывать можно только на то что там либо false, либо все остальное, что интерпретируется как true, но может им и не являться. Т.к. платформа таки допускает другие значения.
Согласен, что разница качественная.

N>Но код, имеющий соответствующие привилегии, может наружить этот инвариант среды выполнения. Это же можно сделать, если залезть в процессор с паяльником.


А для такого кода нужны привилегии?
[StructLayout(LayoutKind.Explicit)]
struct BOOL
{
    [FieldOffset(0)] public byte Byte;
    [FieldOffset(0)] public bool Bool;
}

static void Main()
{
    BOOL b = new BOOL {Byte = 3};
    switch (b.Bool)
    {
        case false:
        case true:
            break;
        default:
            Console.WriteLine("Упс");
            break;
    }
}

Даже если нужны привилегии, то кривой bool мы можем получить как параметр, или в качестве результата другого метода.

Я не призываю проверять значения bool на допустимость, только лишь хотел уточнить, что нет гарантии того что там одно из двух значений.
Re[7]: Смерть булевским аргументам!
От: nikov США http://www.linkedin.com/in/nikov
Дата: 10.09.09 17:57
Оценка:
Здравствуйте, samius, Вы писали:

S>А для такого кода нужны привилегии?

S>
S>[StructLayout(LayoutKind.Explicit)]
S>struct BOOL
S>{
S>    [FieldOffset(0)] public byte Byte;
S>    [FieldOffset(0)] public bool Bool;
S>}

S>static void Main()
S>{
S>    BOOL b = new BOOL {Byte = 3};
S>    switch (b.Bool)
S>    {
S>        case false:
S>        case true:
S>            break;
S>        default:
S>            Console.WriteLine("Упс");
S>            break;
S>    }
S>}
S>


Похоже, что не нужны. Очень плохо...
Re[7]: Смерть булевским аргументам!
От: Кодт Россия  
Дата: 10.09.09 18:42
Оценка:
Здравствуйте, samius, Вы писали:

N>>Всё-таки разница здесь не количественная (проще-сложнее), а качественная. Формально, с точки зрения языка, bool не может содержать других значений.

S>Да, формально с точки зрения языка не может, но рассчитывать можно только на то что там либо false, либо все остальное, что интерпретируется как true, но может им и не являться. Т.к. платформа таки допускает другие значения.
S>Согласен, что разница качественная.

Рассчитывать здесь можно на то, что там находится false, true и мусорные значения, интерпретируемые как попало в зависимости от настроения компилятора.
А настроение у оптимизирующего компилятора может быть очень весёлое.

В случае с энумом — использовать произвольные значения в пределах underlying type легально, это прописано в стандартах языков (C, C++, C#) и является распространённой практикой.

S>Я не призываю проверять значения bool на допустимость, только лишь хотел уточнить, что нет гарантии того что там одно из двух значений.


После забега по памяти вообще все гарантии кончились.

Для целочисленных типов нет априори-мусорных значений. Мусорность определяется уже программистом по месту использования. Ну там ожидаемая делимость, вхождение в диапазон, и т.д.
А вот для вещественных типов, ЕМНИП, можно сделать априори-мусорное значение (элементарно: денормализовать мантиссу). Дальше уже вопрос устойчивости психики у FPU — метнёт оно исключение или просто вычислит какую-нибудь ерунду.
Но это всё разновидности неопределённого поведения — одно повыше уровнем, другое пониже.

Работа с bool — на самом нижнем уровне, просто хотя бы потому, что логика — это первая вещь, которую пытаются оптимизировать.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[8]: Смерть булевским аргументам!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.09.09 19:29
Оценка:
Здравствуйте, Кодт, Вы писали:

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


N>>>Всё-таки разница здесь не количественная (проще-сложнее), а качественная. Формально, с точки зрения языка, bool не может содержать других значений.

S>>Да, формально с точки зрения языка не может, но рассчитывать можно только на то что там либо false, либо все остальное, что интерпретируется как true, но может им и не являться. Т.к. платформа таки допускает другие значения.

К>Рассчитывать здесь можно на то, что там находится false, true и мусорные значения, интерпретируемые как попало в зависимости от настроения компилятора.

Да, так будет правильнее.
К>А настроение у оптимизирующего компилятора может быть очень весёлое.

К>В случае с энумом — использовать произвольные значения в пределах underlying type легально, это прописано в стандартах языков (C, C++, C#) и является распространённой практикой.

Легально все что не запрещено. Засовывать мусор в bool не запрещено, но и не является распространенной практикой. Естественно, засовывающие мусор в bool либо знают чего конкретно добиваются, либо ССЗБ.

S>>Я не призываю проверять значения bool на допустимость, только лишь хотел уточнить, что нет гарантии того что там одно из двух значений.


К>После забега по памяти вообще все гарантии кончились.

Дык и без забега почти, можно сказать. Радует то, что нельзя выравнять поля со ссылками. Но это уже не компилятор запрещает, а рантайм не хочет грузить сборку.

К>Для целочисленных типов нет априори-мусорных значений. Мусорность определяется уже программистом по месту использования. Ну там ожидаемая делимость, вхождение в диапазон, и т.д.

Да, bool таки представлен целочисленным ведь типом?
К>А вот для вещественных типов, ЕМНИП, можно сделать априори-мусорное значение (элементарно: денормализовать мантиссу). Дальше уже вопрос устойчивости психики у FPU — метнёт оно исключение или просто вычислит какую-нибудь ерунду.
К>Но это всё разновидности неопределённого поведения — одно повыше уровнем, другое пониже.

К>Работа с bool — на самом нижнем уровне, просто хотя бы потому, что логика — это первая вещь, которую пытаются оптимизировать.

UB так UB.

Но я не понимаю, чем так плох плюсовый подход к bool-у, когда легально есть FALSE, TRUE и все остальное? Зачем надо было объявлять в языке что может быть только 2 значения? Без каких либо изменений в коде, нужно было бы всего лишь специфицировать поведение компилятора при остальных значениях и ткнуть носом в корректную нормализацию bool-а для тех сценариев, где это важно (например, b = (b == true); — плохо, а b = (b != false); — хорошо)
Re[9]: Смерть булевским аргументам!
От: K13 http://akvis.com
Дата: 11.09.09 03:57
Оценка:
S>Но я не понимаю, чем так плох плюсовый подход к bool-у, когда легально есть FALSE, TRUE и все остальное? Зачем надо было объявлять в языке что может быть только 2 значения? Без каких либо изменений в коде, нужно было бы всего лишь специфицировать поведение компилятора при остальных значениях и ткнуть носом в корректную нормализацию bool-а для тех сценариев, где это важно (например, b = (b == true); — плохо, а b = (b != false); — хорошо)

Это как раз не плюсовый подход. плюсовый -- это true или false + я хотел бы ключик компилятора который кидает исключение на других значениях.

иначе что мы должны делать здесь:
bool xor2( bool a, bool b )
{
  return a != b;  
}


если разрешить "все остальное"? и главное -- _зачем_?
в чем выигрыш от "всего остального"? встретив
bool f = 5;

компилятор сам засунет именно true.
Реально в bool может оказаться мусор либо в виде неинициализированной переменной, либо явного затирания через приведение указателя / потоптанной памяти.
Re[9]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 11.09.09 04:11
Оценка:
Здравствуйте, samius, Вы писали:

К>>Для целочисленных типов нет априори-мусорных значений. Мусорность определяется уже программистом по месту использования. Ну там ожидаемая делимость, вхождение в диапазон, и т.д.

S>Да, bool таки представлен целочисленным ведь типом?
Нет, bool — это самостоятельный тип, в числе других целочисленных типов.

S>Но я не понимаю, чем так плох плюсовый подход к bool-у, когда легально есть FALSE, TRUE и все остальное? Зачем надо было объявлять в языке что может быть только 2 значения? Без каких либо изменений в коде, нужно было бы всего лишь специфицировать поведение компилятора при остальных значениях и ткнуть носом в корректную нормализацию bool-а для тех сценариев, где это важно (например, b = (b == true); — плохо, а b = (b != false); — хорошо)


Если мы говорим о С++, то легально есть только true и false, нету никакого "всего остального":

Values of type bool are either true or false.42)

42) Using a bool value in ways described by this International Standard as ‘‘undefined,’’ such as by examining the value of an uninitialized automatic variable, might cause it to behave as if it is neither true nor false.

jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[10]: Смерть булевским аргументам!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 11.09.09 06:05
Оценка:
Здравствуйте, K13, Вы писали:

S>>Но я не понимаю, чем так плох плюсовый подход к bool-у, когда легально есть FALSE, TRUE и все остальное? Зачем надо было объявлять в языке что может быть только 2 значения? Без каких либо изменений в коде, нужно было бы всего лишь специфицировать поведение компилятора при остальных значениях и ткнуть носом в корректную нормализацию bool-а для тех сценариев, где это важно (например, b = (b == true); — плохо, а b = (b != false); — хорошо)


K13>Это как раз не плюсовый подход. плюсовый -- это true или false + я хотел бы ключик компилятора который кидает исключение на других значениях.

Значит попутал малосьть.

K13>иначе что мы должны делать здесь:

K13>
K13>bool xor2( bool a, bool b )
K13>{
K13>  return a != b;  
K13>}
K13>

Здесь пусть будет как есть, естественно работать будет только на "хороших" булах.

K13>если разрешить "все остальное"? и главное -- _зачем_?

K13>в чем выигрыш от "всего остального"? встретив
K13>
bool f = 5;

K13>компилятор сам засунет именно true.
Я не совсем правильно выразился. Я не хотел на уровне языка засовывать в bool все остальное, я предложил что-то вроде "хоть мы и как-бы ограничили возможность инициализации bool только двумя значениями, но фактически там может оказаться что-то другое, и потому результат сравнения, либо переход по switch могут дать неожиданный результат. Нормализуйте bool сами там где это важно.".
А фактически мы имеем "The possible values of type bool are true and false." и всякое UB при impossible values.

K13>Реально в bool может оказаться мусор либо в виде неинициализированной переменной, либо явного затирания через приведение указателя / потоптанной памяти.

Как оказалось есть, вполне легальные способы получить мусор в bool через выравнивание полей. А единожды полученный, он может расползтись по программе через присваивания и давать неожиданные эффекты.
Re[10]: Смерть булевским аргументам!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 11.09.09 06:14
Оценка:
Здравствуйте, jazzer, Вы писали:

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


К>>>Для целочисленных типов нет априори-мусорных значений. Мусорность определяется уже программистом по месту использования. Ну там ожидаемая делимость, вхождение в диапазон, и т.д.

S>>Да, bool таки представлен целочисленным ведь типом?
J>Нет, bool — это самостоятельный тип, в числе других целочисленных типов.

S>>Но я не понимаю, чем так плох плюсовый подход к bool-у, когда легально есть FALSE, TRUE и все остальное? Зачем надо было объявлять в языке что может быть только 2 значения? Без каких либо изменений в коде, нужно было бы всего лишь специфицировать поведение компилятора при остальных значениях и ткнуть носом в корректную нормализацию bool-а для тех сценариев, где это важно (например, b = (b == true); — плохо, а b = (b != false); — хорошо)


J>Если мы говорим о С++, то легально есть только true и false, нету никакого "всего остального":

J>

J>Values of type bool are either true or false.42)

J>42) Using a bool value in ways described by this International Standard as ‘‘undefined,’’ such as by examining the value of an uninitialized automatic variable, might cause it to behave as if it is neither true nor false.

ООООООООООО!
Т.е. в случае плюсов мы готовы к тому что там может быть что-то еще. А в случае шарпа — нет.
Re[11]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 11.09.09 06:32
Оценка:
Здравствуйте, samius, Вы писали:

J>>Если мы говорим о С++, то легально есть только true и false, нету никакого "всего остального":

J>>

J>>Values of type bool are either true or false.42)

J>>42) Using a bool value in ways described by this International Standard as ‘‘undefined,’’ such as by examining the value of an uninitialized automatic variable, might cause it to behave as if it is neither true nor false.

S>ООООООООООО!
S>Т.е. в случае плюсов мы готовы к тому что там может быть что-то еще. А в случае шарпа — нет.

Не понял, каким образом мы "готовы". Программа с неопределенным поведением — это некорректная программа, которая может делать все, что угодно (обычно она просто форматирует винчестер). Стандарт никак не описывает поведение некорректных программ.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Смерть булевским аргументам!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 11.09.09 07:13
Оценка: -1
Здравствуйте, Pavel Dvorkin, Вы писали:

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


J>>Robert C. Martin's Clean Code Tip #12: Eliminate Boolean Arguments

J>>http://www.informit.com/articles/article.aspx?p=1392524

PD>Кое-что по существу верно, но вообще — проблема ИМХО не стоит выеденного яйца.


Проблема, которая даёт такой неприятный для человека эффект (я про сложность вообще осознания того, что две схожие функции получают данные противоположным образом) — она очень даже стоит, и даже тысячи невыеденных яиц. Вообще, получился хороший пример как на ровном месте сделать obfuscating коду.
The God is real, unless declared integer.
Re[3]: Смерть булевским аргументам!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 11.09.09 07:20
Оценка:
Здравствуйте, jazzer, Вы писали:

I>>Все в сослагательном наклонении, потому-что конкретная проблема надумана, аргумент конечно же должен задаваться в радианах.

J>Можете выбрать любой цвет, при условии что вы выбираете черный :)
J>Не все так однозначно.
J>Градусы хороши своей целочисленностью.

Не целочисленностью, конечно же — вон Земля наклонена примерно под 23.45 градусов (23 градуса 27 минут). А значительно большей естественностью для человека. Анализировать внутри программы поворот на 30 градусов как-то проще, чем на 0.52 радиана.

Автопилот совершенно естественно может давать корректировки на нецелое число градусов (хотя вот он будет скорее всего считать в радианах).

I>>Возможно стоит добавить, что это преобразование нужно выполнять только при вводе информации от пользователя, внутри программа должна иметь дело только с радианами.

J>см. выше.
J>То же, кстати, относится к доброй половине финансовых программ, где цены, вроде как, не целые, но из лучше хранить как целые или как пару целых.

Там — да, тут — не вижу основания для перехода на целые.

I>>PS. Этот автор у тебя тоже в числе экспертов?

J>Я *там* в качестве эксперта упоминал Глассборо — есть сомнения, что он эксперт? Тот, кого ты *там* нашел, я впервые увидел. Ладно, здесь это офтопик в любом случае.
J>А эта конкретная статья в RSS прилетела, посмеялся, пока читал, решил сюда запостить.
J>Надеюсь, что вы тоже посмеялись.

Скорее поплакали.:)))

J>С другой стороны, хоть и смешно, но проблема реальная: во многих признанных API (в винде, например) булевские переменные летают только в путь, в результате смотришь в вызов функции с пятью true, как дурак, и пытаешься понять, что же они все означают.


Ну там системное API, что поделать.
Хотя если бы аргументы были гарантированно названы и язык позволял (как C++) — можно было бы писать SysCloseDoor(hDoor, immediately = true, ignore_obstacle = true, lock = false). Я так делаю в Питоне, потому что удобнее.:) хотя в рантайме и чуть дороже.

J>Так что мысль вроде как и очевидна, да, видать, лень побеждает — bool же проще сунуть, чем целое перечисление объявлять или вообще специальный полноценный тип ваять.


Так её надо побеждать встречной ленью — дебажить полученное.;))
The God is real, unless declared integer.
Re[4]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 11.09.09 07:30
Оценка:
Здравствуйте, netch80, Вы писали:

J>>Градусы хороши своей целочисленностью.


N>Не целочисленностью, конечно же — вон Земля наклонена примерно под 23.45 градусов (23 градуса 27 минут). А значительно большей естественностью для человека. Анализировать внутри программы поворот на 30 градусов как-то проще, чем на 0.52 радиана.


Нет, именно целочисленностью. Всякие градусы типа 45, 90, 180, 360 имеют вполне однозначное толкование, в отличие от иррационального пи, которое непонятно с какой точностью записывать.

Например, поворот картинки на 180 тривиален, а на пи — попробуй еще разберись, что ошибка в 24-м знаке — это ошибка представления, а не то, что тебе нужно именно на такой вот кривой угод повернуть.

Естественность для человека тут ни при чем, просто целые радианы практического смысла не имеют никакого, в отличие от целых градусов (именно потому что круг поделили на целое количество частей).

N>Ну там системное API, что поделать.

N>Хотя если бы аргументы были гарантированно названы и язык позволял (как C++) — можно было бы писать SysCloseDoor(hDoor, immediately = true, ignore_obstacle = true, lock = false). Я так делаю в Питоне, потому что удобнее. хотя в рантайме и чуть дороже.

Ну так от питона никто скорости и не ждет
так что в питоне все так делают

J>>Так что мысль вроде как и очевидна, да, видать, лень побеждает — bool же проще сунуть, чем целое перечисление объявлять или вообще специальный полноценный тип ваять.


N>Так её надо побеждать встречной ленью — дебажить полученное.)

не понял, кто в данном случае "встречно ленится"...
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: Смерть булевским аргументам!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 11.09.09 07:46
Оценка:
Здравствуйте, jazzer, Вы писали:

J>>>Градусы хороши своей целочисленностью.

N>>Не целочисленностью, конечно же — вон Земля наклонена примерно под 23.45 градусов (23 градуса 27 минут). А значительно большей естественностью для человека. Анализировать внутри программы поворот на 30 градусов как-то проще, чем на 0.52 радиана.
J>Нет, именно целочисленностью. Всякие градусы типа 45, 90, 180, 360 имеют вполне однозначное толкование, в отличие от иррационального пи, которое непонятно с какой точностью записывать.
J>Например, поворот картинки на 180 тривиален, а на пи — попробуй еще разберись, что ошибка в 24-м знаке — это ошибка представления, а не то, что тебе нужно именно на такой вот кривой угод повернуть.

Твоя идея понятна, но не приемлема:

1. То, о чём ты говоришь, фактически означает не "целое число градусов", а "целое конкретное число градусов из набора фиксированных значений, которые имеют свой отдельный смысл" (180 — пол-круга, 90 — четверть круга или прямой угол, и так далее). Потому что поворот на 180, например, чётко определён именно в градусах как половина круга и это имеет смысл тем, что упрощает реализацию; а вот поворот на 25 или 26 градусов у тебя будет одинаково трудоёмок что в радианах, что в градусах.
2. В контексте исходной статьи это всё не имеет значения — задать самолёту разворот на 180 градусов, на 3.14 радиана или 3.15 — всё равно воздушные потоки и прочие левые факторы внесут свою коррективу, и на половине поворота (скорее даже раньше) придётся это исправлять.

J>Естественность для человека тут ни при чем, просто целые радианы практического смысла не имеют никакого, в отличие от целых градусов (именно потому что круг поделили на целое количество частей).


Целые радианы имеют значительно больше практического смысла, чем целые градусы. Радианы не только не зависят от того, сколько у тебя пальцев или чем ты думаешь — они упрощают практически все тригонометрические формулы. Иначе бы их не вводили. А градусы — это индивидуальны.

Не знаю, в курсе ли ты, но есть так называемые "грады", коих в прямом углу не 90, а 100. Они приняты в ряде специфических областей инженерии. И практически они не сильно хуже. А вот радианную меру ты на 1.2 или 0.9 не умножишь — чушь получится.

N>>Ну там системное API, что поделать.

N>>Хотя если бы аргументы были гарантированно названы и язык позволял (как C++) — можно было бы писать SysCloseDoor(hDoor, immediately = true, ignore_obstacle = true, lock = false). Я так делаю в Питоне, потому что удобнее.:) хотя в рантайме и чуть дороже.
J>Ну так от питона никто скорости и не ждет :)
J>так что в питоне все так делают

А в компилируемых языках можно это возложить на компилятор. Просто не припекло.

J>>>Так что мысль вроде как и очевидна, да, видать, лень побеждает — bool же проще сунуть, чем целое перечисление объявлять или вообще специальный полноценный тип ваять.

N>>Так её надо побеждать встречной ленью — дебажить полученное.;))
J>не понял, кто в данном случае "встречно ленится"...

Тот, кому это дальше расчищать и по последствиям расчистки — рефакторить.
The God is real, unless declared integer.
Re[12]: Смерть булевским аргументам!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 11.09.09 08:12
Оценка:
Здравствуйте, jazzer, Вы писали:

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


S>>Т.е. в случае плюсов мы готовы к тому что там может быть что-то еще. А в случае шарпа — нет.


J>Не понял, каким образом мы "готовы". Программа с неопределенным поведением — это некорректная программа, которая может делать все, что угодно (обычно она просто форматирует винчестер). Стандарт никак не описывает поведение некорректных программ.

мы "готовы" значит что программист, прочитавший спецификацию, предупрежден о том что там может быть не true и не false.
Re[8]: Смерть булевским аргументам!
От: wallaby  
Дата: 11.09.09 08:17
Оценка:
Здравствуйте, Кодт, Вы писали:

К>А вот для вещественных типов, ЕМНИП, можно сделать априори-мусорное значение (элементарно: денормализовать мантиссу).


Но как, Холмс? ЕМНИП мантисса вещественного числа хранится без старшего бита (который подразумевается единичным для всех значений экспоненты кроме 0 (0) и 3ff (NaN)) и не может быть ненормализованной. "Испортить" вещественное число наверно можно например записав в экспоненту 0 а в мантиссу не 0, хотя в этом случае FPU скорее всего просто проигнорирует биты мантиссы.
---
The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true
Re[6]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 11.09.09 08:18
Оценка:
Здравствуйте, netch80, Вы писали:

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


J>>>>Градусы хороши своей целочисленностью.

N>>>Не целочисленностью, конечно же — вон Земля наклонена примерно под 23.45 градусов (23 градуса 27 минут). А значительно большей естественностью для человека. Анализировать внутри программы поворот на 30 градусов как-то проще, чем на 0.52 радиана.
J>>Нет, именно целочисленностью. Всякие градусы типа 45, 90, 180, 360 имеют вполне однозначное толкование, в отличие от иррационального пи, которое непонятно с какой точностью записывать.
J>>Например, поворот картинки на 180 тривиален, а на пи — попробуй еще разберись, что ошибка в 24-м знаке — это ошибка представления, а не то, что тебе нужно именно на такой вот кривой угод повернуть.

N>Твоя идея понятна, но не приемлема:


N>1. То, о чём ты говоришь, фактически означает не "целое число градусов", а "целое конкретное число градусов из набора фиксированных значений, которые имеют свой отдельный смысл" (180 — пол-круга, 90 — четверть круга или прямой угол, и так далее). Потому что поворот на 180, например, чётко определён именно в градусах как половина круга и это имеет смысл тем, что упрощает реализацию; а вот поворот на 25 или 26 градусов у тебя будет одинаково трудоёмок что в радианах, что в градусах.


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

N>2. В контексте исходной статьи это всё не имеет значения — задать самолёту разворот на 180 градусов, на 3.14 радиана или 3.15 — всё равно воздушные потоки и прочие левые факторы внесут свою коррективу, и на половине поворота (скорее даже раньше) придётся это исправлять.


Это да. В этой конкретной задаче никакой разницы.

J>>Естественность для человека тут ни при чем, просто целые радианы практического смысла не имеют никакого, в отличие от целых градусов (именно потому что круг поделили на целое количество частей).


N>Целые радианы имеют значительно больше практического смысла, чем целые градусы. Радианы не только не зависят от того, сколько у тебя пальцев или чем ты думаешь — они упрощают практически все тригонометрические формулы. Иначе бы их не вводили. А градусы — это индивидуальны.


Да ладно. Все наоборот. Раз ты завёл речь о тригонометрии — чему равен синус 180 градусов? а синус 3.1415926? а синус 3.1415926535?

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

N>Не знаю, в курсе ли ты, но есть так называемые "грады", коих в прямом углу не 90, а 100. Они приняты в ряде специфических областей инженерии. И практически они не сильно хуже. А вот радианную меру ты на 1.2 или 0.9 не умножишь — чушь получится.


В курсе. и градусы, и грады лучше радианов, именно потому что целочисленные.

N>А в компилируемых языках можно это возложить на компилятор. Просто не припекло.

Мороки много просто. Есть же Boost.Parameter.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: Смерть булевским аргументам!
От: Кодт Россия  
Дата: 11.09.09 08:24
Оценка:
Здравствуйте, wallaby, Вы писали:

К>>А вот для вещественных типов, ЕМНИП, можно сделать априори-мусорное значение (элементарно: денормализовать мантиссу).


W>Но как, Холмс? ЕМНИП мантисса вещественного числа хранится без старшего бита (который подразумевается единичным для всех значений экспоненты кроме 0 (0) и 3ff (NaN)) и не может быть ненормализованной. "Испортить" вещественное число наверно можно например записав в экспоненту 0 а в мантиссу не 0, хотя в этом случае FPU скорее всего просто проигнорирует биты мантиссы.


Возможно, что здесь как раз мне изменила память
Перекуём баги на фичи!
Re[13]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 11.09.09 08:28
Оценка:
Здравствуйте, samius, Вы писали:

S>мы "готовы" значит что программист, прочитавший спецификацию, предупрежден о том что там может быть не true и не false.


а... ну так это относится ко всем типам, в общем-то, не только к bool.
И если программист пишет програму так, чтоб не возникало UB, то ему и не надо быть ни к чему готовым.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[14]: Смерть булевским аргументам!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 11.09.09 08:41
Оценка:
Здравствуйте, jazzer, Вы писали:

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


S>>мы "готовы" значит что программист, прочитавший спецификацию, предупрежден о том что там может быть не true и не false.


J>а... ну так это относится ко всем типам, в общем-то, не только к bool.

не совсем. Испортить ссылку нам в шарпе не дадут. Хотя подменить тип ссылки можно тем же способом.

J>И если программист пишет програму так, чтоб не возникало UB, то ему и не надо быть ни к чему готовым.

Или ко всему готовым?
Re[15]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 11.09.09 08:44
Оценка: +1
Здравствуйте, samius, Вы писали:

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


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


S>>>мы "готовы" значит что программист, прочитавший спецификацию, предупрежден о том что там может быть не true и не false.


J>>а... ну так это относится ко всем типам, в общем-то, не только к bool.

S>не совсем. Испортить ссылку нам в шарпе не дадут. Хотя подменить тип ссылки можно тем же способом.
Я про плюсы.

J>>И если программист пишет програму так, чтоб не возникало UB, то ему и не надо быть ни к чему готовым.

S>Или ко всему готовым?
Не вижу смысла быть ко всему готовым.
Имхо, вполне достаточно писать в терминах корректной программы, иначе вместо нормальной программы будут сплошные проверки типа this != NULL.
Ко всему готовым нужно быть только при валидации внешних данных.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[16]: Смерть булевским аргументам!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 11.09.09 09:02
Оценка:
Здравствуйте, jazzer, Вы писали:

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


J>>>а... ну так это относится ко всем типам, в общем-то, не только к bool.

S>>не совсем. Испортить ссылку нам в шарпе не дадут. Хотя подменить тип ссылки можно тем же способом.
J>Я про плюсы.
аа, ну в плюсах все по-другому воспринимается, т.к. там никто не защищает от хождения по граблям, потолку и т.п. А в шарпе нас от всего "защищают", но как-бы не до конца.

J>>>И если программист пишет програму так, чтоб не возникало UB, то ему и не надо быть ни к чему готовым.

S>>Или ко всему готовым?
J>Не вижу смысла быть ко всему готовым.
J>Имхо, вполне достаточно писать в терминах корректной программы, иначе вместо нормальной программы будут сплошные проверки типа this != NULL.
J>Ко всему готовым нужно быть только при валидации внешних данных.
Согласен. Если мы внутри сами случайно данные не сломаем, а таки чтобы сломать в шарпе bool, надо приложить некоторые усилия, то внутри бояться мусора в bool-е не следует.
Проверять ли внешние bool параметры на мусор? Имхо — не стоит. Но стоит вообще аккуратнее относитсья к сравнению bool-ов, а так же не использовать метку true в switch-е (только false и default).
Re[10]: Смерть булевским аргументам!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 11.09.09 09:43
Оценка:
Здравствуйте, Кодт, Вы писали:

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


К>>>А вот для вещественных типов, ЕМНИП, можно сделать априори-мусорное значение (элементарно: денормализовать мантиссу).


W>>Но как, Холмс? ЕМНИП мантисса вещественного числа хранится без старшего бита (который подразумевается единичным для всех значений экспоненты кроме 0 (0) и 3ff (NaN)) и не может быть ненормализованной. "Испортить" вещественное число наверно можно например записав в экспоненту 0 а в мантиссу не 0, хотя в этом случае FPU скорее всего просто проигнорирует биты мантиссы.


К>Возможно, что здесь как раз мне изменила память :shuffle:


Наверняка. В реализациях с принудительной нормализацией (как IEEE754 и он на x86) такое невозможно из-за скрытого старшего, а в реализациях без этого (long double на x86, S/360 и так далее) денормализованное представление является штатным.

Поэтому, априори-мусорное на них выделяется отдельно (в том же IEEE754 — NaN содержит область целого параметра, который должен быть не равен 0, и тем самым может передавать много разных ситуаций).
The God is real, unless declared integer.
Re[7]: Смерть булевским аргументам!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 11.09.09 10:06
Оценка:
Здравствуйте, jazzer, Вы писали:

N>>1. То, о чём ты говоришь, фактически означает не "целое число градусов", а "целое конкретное число градусов из набора фиксированных значений, которые имеют свой отдельный смысл" (180 — пол-круга, 90 — четверть круга или прямой угол, и так далее). Потому что поворот на 180, например, чётко определён именно в градусах как половина круга и это имеет смысл тем, что упрощает реализацию; а вот поворот на 25 или 26 градусов у тебя будет одинаково трудоёмок что в радианах, что в градусах.

J>ну то есть в основном одинаково трудоемко, но в градусной мере есть выделенные точки, в которых радикально менее трудоемко.

Да.

J>Стало быть, градусы лучше, чем радианы; непонятно, почему ты говоришь, что идея неприемлема :xz:


Потому что это 1) не специфика градусов (это не основное), 2) не основание считать градусы только целочисленными (а вот это уже основное). Точно так же вместо градусной меры можно было передавать долю круга в float (то есть 1.0 соответствует 360 градусам): так как 1/4 точно представимо и в двоичной, и в десятичной плавучке — результат достигается и определить случай простого поворота можно точно.

J>>>Естественность для человека тут ни при чем, просто целые радианы практического смысла не имеют никакого, в отличие от целых градусов (именно потому что круг поделили на целое количество частей).

N>>Целые радианы имеют значительно больше практического смысла, чем целые градусы. Радианы не только не зависят от того, сколько у тебя пальцев или чем ты думаешь — они упрощают практически все тригонометрические формулы. Иначе бы их не вводили. А градусы — это индивидуальны.
J>Да ладно. Все наоборот. Раз ты завёл речь о тригонометрии — чему равен синус 180 градусов? а синус 3.1415926?

Последнее — что-то около 0.0000000535..., потому что синус на таких углах — практически линейная функция. А что? ;))

J> а синус 3.1415926535?


Аналогично 0.000000000089... только зачем ты путаешь локальную практику человечества последних ~500 лет с фундаментальными основами?

J>Формулам пофиг, там все с точностью до множителя, а вот в реальной машинной жизни все сильно портится, потому что этот множитель иррационален и непредставим в десятичной записи (вернее, ни в какой разрядной записи непредставим).


Не, ты не понял. Формулам не пофиг, потому что в них множителя этого вообще нет. Как считается синус в радианах? x — x**3/fact(3) + x**5/fact(5) — x**7/fact(7)... А как в градусах? Вот тут собственно появляется множитель, а затем берётся всё та же формула для радианов. (Машинные оптимизации этих формул давай тут не обсуждать) Вот я про это.

N>>А в компилируемых языках можно это возложить на компилятор. Просто не припекло.

J>Мороки много просто. Есть же Boost.Parameter.

Оно достаточно эффективно?
The God is real, unless declared integer.
Re[8]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 11.09.09 10:36
Оценка:
Здравствуйте, netch80, Вы писали:

J>>Стало быть, градусы лучше, чем радианы; непонятно, почему ты говоришь, что идея неприемлема


N>Потому что это 1) не специфика градусов (это не основное), 2) не основание считать градусы только целочисленными (а вот это уже основное). Точно так же вместо градусной меры можно было передавать долю круга в float (то есть 1.0 соответствует 360 градусам): так как 1/4 точно представимо и в двоичной, и в десятичной плавучке — результат достигается и определить случай простого поворота можно точно.


Да, это тоже решение, в этом смысле аналогичное градусам (определенные углы становятся представимыми точно).
Но у радианов и того нету.
1 радиан не имеет никакого практического смысла.

J>>Да ладно. Все наоборот. Раз ты завёл речь о тригонометрии — чему равен синус 180 градусов? а синус 3.1415926?

N>Последнее — что-то около 0.0000000535..., потому что синус на таких углах — практически линейная функция. А что? )
J>> а синус 3.1415926535?
N>Аналогично 0.000000000089... только зачем ты путаешь локальную практику человечества последних ~500 лет с фундаментальными основами?
Да потому что мы говорим о реальных системах,а не о фундаментальных основах. Потому что в фундаментальных основах наличие или отсутствие множителя ну никакой роли не играет вообще. А вот на практике — играет, и еще какую.
Типа синус 180 градусов равен точно нулю, а не вот эти все циферки после запятой, что ты нарисовал.
А особенно это заметно будет, когда мы поделим на этот синус.

J>>Формулам пофиг, там все с точностью до множителя, а вот в реальной машинной жизни все сильно портится, потому что этот множитель иррационален и непредставим в десятичной записи (вернее, ни в какой разрядной записи непредставим).


N>Не, ты не понял. Формулам не пофиг, потому что в них множителя этого вообще нет. Как считается синус в радианах? x — x**3/fact(3) + x**5/fact(5) — x**7/fact(7)... А как в градусах? Вот тут собственно появляется множитель, а затем берётся всё та же формула для радианов. (Машинные оптимизации этих формул давай тут не обсуждать) Вот я про это.

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

Я не могу понять, с чем ты споришь, при том что сам признаешь, что у градусов/градов/долей круга есть преимущество перед радианами благодаря наличию особых точек, в которых нечто можно посчитать оптимально.
И вообще все это офтопик, мы тут типа булевские аргументы обсуждаем

J>>Мороки много просто. Есть же Boost.Parameter.

N>Оно достаточно эффективно?
Понятия не имею, не юзал.
Думаю, особого оверхеда там не должно быть.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: Смерть булевским аргументам!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 11.09.09 12:00
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Да, это тоже решение, в этом смысле аналогичное градусам (определенные углы становятся представимыми точно).

J>Но у радианов и того нету.
J>1 радиан не имеет никакого практического смысла.

Как это не имеет? У него длина дуги равна радиусу. Вот ты едешь по МКАД, проехал 22 километра — проехал около радиана.

N>>Аналогично 0.000000000089... только зачем ты путаешь локальную практику человечества последних ~500 лет с фундаментальными основами?

J>Да потому что мы говорим о реальных системах,а не о фундаментальных основах. Потому что в фундаментальных основах наличие или отсутствие множителя ну никакой роли не играет вообще. А вот на практике — играет, и еще какую.
J>Типа синус 180 градусов равен точно нулю, а не вот эти все циферки после запятой, что ты нарисовал.
J>А особенно это заметно будет, когда мы поделим на этот синус.

Зачем на него делить в окрестностях нуля??? Я резко возражаю против этого безумия. Задача с таким делением некорректна и требует переделки начиная с постановки.

J>Но при этом для определенных углов ты можешь вычислить формулы точно, безо всяких рядов, а для всех остальных юзать ряды.

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

Изначально я возражал на твоё утверждение, что "градусы хороши своей целочисленностью". Если бы ты сделал в данном случае API с приёмом только градусов и только целыми, это, может, и работало бы для разворота "кру-гом!", но для мягких корректировок курса уже работать не будет, и у тебя автопилот будет слишком грубым.
Далее, геометрические расчёты курса наверняка ведутся именно в радианах. Никто их ради такого API в градусы пересчитывать не будет. И опять-таки аргумент в пользу представления в радианах (не обязательно только в них).

J>И вообще все это офтопик, мы тут типа булевские аргументы обсуждаем :beer:


Я не знаю, что там обсуждать в булевских аргументах. Обсуждение "какие языки умеют что-то ещё кроме true и false и чем это грозит", конечно, познавательно, но мне в нём смысла ноль целых фиг десятых. Кривизну API и желательность передавать дополнительные слова вроде бы уже все утвердили. Пусть себе обсуждают где какой bool, это не моя тема.

J>>>Мороки много просто. Есть же Boost.Parameter.

N>>Оно достаточно эффективно?
J>Понятия не имею, не юзал.
J>Думаю, особого оверхеда там не должно быть.

Ну осталось найти за пределами C++ достойный аналог. ;)
The God is real, unless declared integer.
Re[7]: Смерть булевским аргументам!
От: Mr.Cat  
Дата: 11.09.09 12:19
Оценка:
Здравствуйте, jazzer, Вы писали:
J>Да ладно. Все наоборот. Раз ты завёл речь о тригонометрии — чему равен синус 180 градусов? а синус 3.1415926? а синус 3.1415926535?
Если тебе нужна 100% точность — ты никуда не сбежишь от символьных вычислений, а там что π, что 180 — один фиг.
Re[9]: Смерть булевским аргументам!
От: Mr.Cat  
Дата: 11.09.09 12:20
Оценка:
Здравствуйте, jazzer, Вы писали:
J>1 радиан не имеет никакого практического смысла.
1 градус тоже.
Re[8]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 11.09.09 14:30
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

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

J>>Да ладно. Все наоборот. Раз ты завёл речь о тригонометрии — чему равен синус 180 градусов? а синус 3.1415926? а синус 3.1415926535?
MC>Если тебе нужна 100% точность — ты никуда не сбежишь от символьных вычислений, а там что π, что 180 — один фиг.

180 градусов — это точное значение. И в формате с плавающей запятой оно точно представимо.
В отличие от.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: Смерть булевским аргументам!
От: Mr.Cat  
Дата: 11.09.09 14:46
Оценка:
Здравствуйте, jazzer, Вы писали:
J>180 градусов — это точное значение. И в формате с плавающей запятой оно точно представимо.
И как ты этот факт собираешься использовать? Сравнивать некое значение с константой 180? Чем это будет отличаться от сравнения с константой M_PI?
Re[10]: Смерть булевским аргументам!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 11.09.09 21:27
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

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

J>>180 градусов — это точное значение. И в формате с плавающей запятой оно точно представимо.
MC>И как ты этот факт собираешься использовать? Сравнивать некое значение с константой 180? Чем это будет отличаться от сравнения с константой M_PI?

Например, тем, что M_PI может пострадать при компиляции от конверсии из текстового вида в плавучку и дать ошибку в каком-то знаке после запятой. И тут уже надо думать не про сравнение на равенство, а сравнение на abs(a-b)<min_delta, как принято для плавучки. А выбор delta сильно зависит от задачи.
The God is real, unless declared integer.
Re[11]: Смерть булевским аргументам!
От: Mr.Cat  
Дата: 11.09.09 21:54
Оценка:
Здравствуйте, netch80, Вы писали:
N>Например, тем, что M_PI может пострадать при компиляции от конверсии из текстового вида в плавучку и дать ошибку в каком-то знаке после запятой. И тут
уже надо думать не про сравнение на равенство, а сравнение на abs(a-b)<min_delta, как принято для плавучки. А выбор delta сильно зависит от задачи.
Ну так и со 180.ровно тоже нельзя просто так сравнивать.
Re[12]: Смерть булевским аргументам!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 11.09.09 21:55
Оценка: 1 (1)
Здравствуйте, Mr.Cat, Вы писали:

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

N>>Например, тем, что M_PI может пострадать при компиляции от конверсии из текстового вида в плавучку и дать ошибку в каком-то знаке после запятой. И тут
MC>уже надо думать не про сравнение на равенство, а сравнение на abs(a-b)<min_delta, как принято для плавучки. А выбор delta сильно зависит от задачи.
MC>Ну так и со 180.ровно тоже нельзя просто так сравнивать.

Если оно возникло именно как 180, а не результат сложных вычислений — то можно и нужно.
The God is real, unless declared integer.
Re[13]: Смерть булевским аргументам!
От: Mr.Cat  
Дата: 11.09.09 22:02
Оценка:
Здравствуйте, netch80, Вы писали:
N>Если оно возникло именно как 180, а не результат сложных вычислений — то можно и нужно.
Если нечто возникто как 180, то сравнивать его со 180, пожалуй, нет смысла.
Но вот в осмысленном случае, когда одно возникло как результат вычислений, а другое — 180 — то сравнивать просто на равенство, как ты сам сказал, не получится.
Re[10]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 12.09.09 01:04
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

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

J>>180 градусов — это точное значение. И в формате с плавающей запятой оно точно представимо.
MC>И как ты этот факт собираешься использовать? Сравнивать некое значение с константой 180? Чем это будет отличаться от сравнения с константой M_PI?

Иди почитай где-нть про сравнение чисел с плавающей запятой на равенство, в сети море информации на эту тему....
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[11]: Смерть булевским аргументам!
От: igna Россия  
Дата: 12.09.09 05:40
Оценка:
Здравствуйте, jazzer, Вы писали:

MC>>И как ты этот факт собираешься использовать? Сравнивать некое значение с константой 180? Чем это будет отличаться от сравнения с константой M_PI?


J>Иди почитай где-нть про сравнение чисел с плавающей запятой на равенство, в сети море информации на эту тему....


Сравнивать вычисленные значения нельзя, присвоенные — можно (если осторожно). И то, и другое относится как к сравнению со 180.0, так и к сравнению с M_PI.

Пока ты оставался с целочисленным 180, у тебя была хоть какая-то (полувразумительная) почва под ногами, после того, как ты перешел к значению с плавающей запятой 180.0, в пользу градусов остался пожалуй единственный аргумент: некоторое удобство при отладке. Но оно сильно субъективно, а тормоза при вычислениях объективны.
Re[11]: Смерть булевским аргументам!
От: Mr.Cat  
Дата: 12.09.09 06:27
Оценка: +1
Здравствуйте, jazzer, Вы писали:
J>Иди почитай где-нть про сравнение чисел с плавающей запятой на равенство, в сети море информации на эту тему....
Вот ведь как — достаточно обвинить оппонента в невежестве и его сообщения можно не читать. Да?
Re[11]: Смерть булевским аргументам!
От: igna Россия  
Дата: 12.09.09 08:20
Оценка:
Здравствуйте, netch80, Вы писали:

N>Например, тем, что M_PI может пострадать при компиляции от конверсии из текстового вида в плавучку и дать ошибку в каком-то знаке после запятой.


Ну так ты и сравнивай его на равенство с таким пострадавшим от того же компилятора M_PI. А на то, что какое-либо значение, в том числе 180.0, одинаково пострадает от двух разных компиляторов, я бы полагаться не стал.

Кстати, FPU хоть считают равными 180,0 и 179,(9)?
Re[12]: Смерть булевским аргументам!
От: nikov США http://www.linkedin.com/in/nikov
Дата: 12.09.09 08:40
Оценка:
Здравствуйте, igna, Вы писали:

I>Ну так ты и сравнивай его на равенство с таким пострадавшим от того же компилятора M_PI. А на то, что какое-либо значение, в том числе 180.0, одинаково пострадает от двух разных компиляторов, я бы полагаться не стал.


То, что компилятор один и тот же, ещё ничего не гарантирует.

using System;

static class Program
{
  static void Main()
  {
      Console.WriteLine((int) (195.95f * 100)); // 19594

      float f = 195.95f;
      Console.WriteLine((int) (f * 100)); // 19595
  }
}


И это не баг.
Re[13]: Смерть булевским аргументам!
От: igna Россия  
Дата: 12.09.09 09:02
Оценка:
Здравствуйте, nikov, Вы писали:

N>То, что компилятор один и тот же, ещё ничего не гарантирует.


N>      Console.WriteLine((int) (195.95f * 100)); // 19594

N>      float f = 195.95f;
N>      Console.WriteLine((int) (f * 100)); // 19595


Ты не понял, речь о программном сравнении, причем допустимом только в случае отсутствия вычислений. В твоем примере программного сравнения вообще нет, сравнивает человек, зато есть вычисление.
Re: Смерть булевским аргументам!
От: skeptik_  
Дата: 12.09.09 16:47
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Robert C. Martin's Clean Code Tip #12: Eliminate Boolean Arguments

J>http://www.informit.com/articles/article.aspx?p=1392524

Если это С++, то надо было просто заюзать Boost.Units, и путаница просто не смогла бы возникнуть. Это также куда лучшее решение чем incrementallyRotateQuarterTurn/rotateByDegrees/rotateByRadians.
Re[12]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 12.09.09 19:48
Оценка:
Здравствуйте, igna, Вы писали:

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


MC>>>И как ты этот факт собираешься использовать? Сравнивать некое значение с константой 180? Чем это будет отличаться от сравнения с константой M_PI?


J>>Иди почитай где-нть про сравнение чисел с плавающей запятой на равенство, в сети море информации на эту тему....


I>Сравнивать вычисленные значения нельзя, присвоенные — можно (если осторожно). И то, и другое относится как к сравнению со 180.0, так и к сравнению с M_PI.


Так и представил себе пользователя, вбивающего в окошечко "угод" пи с точностью до хз какого знака после запятой (ему ведь еще откуда-то надо знать, как именно выглядит M_PI на этой конкретной машине) А программа потом радостно сравнивает и говорит пользователю: "Не, это нифига не пи, ты в 54-м знаке ошибся!"

I>Пока ты оставался с целочисленным 180, у тебя была хоть какая-то (полувразумительная) почва под ногами, после того, как ты перешел к значению с плавающей запятой 180.0, в пользу градусов остался пожалуй единственный аргумент: некоторое удобство при отладке. Но оно сильно субъективно, а тормоза при вычислениях объективны.


Если бы это была "какая-то полувразумительная почва под ногами", то тогда в IrfanView, например, не было бы Lossless Jpeg Operation в виде поворота на углы, кратные 90 градусам (или 100 градам, или еще чему угодно, но только не целому числу радиан). Радианы нафиг никому не нужны, не удобны они для практических геометрических задач. Это в абстрактной математике есть совершенно точное число пи, и все формулы замечательно с ними записываются (и там действительно пофиг, радианы это или градусы или еще что), а у нас в компах с этим полная труба, и нам совсем не пофиг.

Например, если у тебя есть прямоугольный треугольник (т.е. с углом в 90 градусов), то ты можешь применять простейшие формулы из теоремы Пифагора и простейшие деления для поиска всяких синусов углов. А для произвольных углов (и для любых углов в радианах) тебе придется поднимать всю тяжелую артиллерию тригонометрии, потому что сравнивать с M_PI — дело неблагодарное.

Я вообще не понимаю, с чем ты споришь.
Твой аргументы аналогичны "для возведения в степень есть страшные формулы, вот и давайте юзать их, а то, что для возведения в степени двойки есть чудесная операция битового сдвига — тем хуже для нее"
ЗЫ Сейчас посмотрел историю — спор с этим аргументом затеял не ты, а netch80 — ну, значит, последний комментарий предназначается ему

Насчет значений с плавающей запятой — есть радикальная разница в представлении 180 и M_PI: 180 всегда представлена точно, а пи так представлена быть не может в принципе, и ты всегда будешь иметь дело с обрезаниями.
Т.е. если у тебя в программе есть поле ввода, откуда ты читаешь число с плавающей запятой, то 180 всегда будет точно 180 (буду рад услышать аргументацию, почему оно не может быть таковым), а вот с пи тебе придется туго.
Естественно, если ты над этими 180 будешь потом изгаляться, в результате у тебя в общем случае получится не точно 180, но если ты берешь как есть — оно будет точным, и в этом нет никакой разницы с целыми числами.
Поправь меня, если это не так.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[13]: Смерть булевским аргументам!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.09 20:45
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Я вообще не понимаю, с чем ты споришь.

J>Твой аргументы аналогичны "для возведения в степень есть страшные формулы, вот и давайте юзать их, а то, что для возведения в степени двойки есть чудесная операция битового сдвига — тем хуже для нее" :xz:
J>ЗЫ Сейчас посмотрел историю — спор с этим аргументом затеял не ты, а netch80 — ну, значит, последний комментарий предназначается ему :shuffle:

Ты гонеш, кросавчег (tm)
Я утверждал совсем не это, а то, что

1) градусы удобны для выделения случая "кратно 90" (как и ты), но при этом не обязательно требовать их целочисленности, если эти кратные 90 значения явно сгенерированы

2) переводить в градусы только ради градусов смысла нет

3) в задаче автопилота точность значений вообще дальше третьего знака нереальна
Как из этого можно сделать вывод, что я предлагаю отказаться от простых путей, где они есть, и начать намеренно усложнять — я не знаю. Наверно, для этого нужен какой-то особый скилл неадекватных выводов:)

А остальное — возражения на отдельные утверждения, которые при в общем правильной общей мысли загоняют её в какие-то крайне нелепые стороны. Если ты из возражений на отдельные частные утверждения делаешь вывод о том, что я тебе тотально противоречу — что ж, придётся повторить вывод про "особый скилл" ;))

J>Насчет значений с плавающей запятой — есть радикальная разница в представлении 180 и M_PI: 180 всегда представлена точно, а пи так представлена быть не может в принципе, и ты всегда будешь иметь дело с обрезаниями.


Угу. Только вот я для проверки аккуратности плавучки нарисовал маленький кусочек кода:

  double v1 = M_PI;
  double v2 = asin(1) * 2;
  double v3 = acos(-1);
  printf("%30.25g %30.25g %30.25g\n", v1, v2, v3);
  printf("v1%sv2 v2%sv3 v3%sv1\n",
    (v1==v2)?"=":"!=", (v2==v3)?"=":"!=", (v3==v1)?"=":"!=");


и как ты думаешь, что он мне выдал? он мне выдал все три равенства. Фря/7.2/i386.

Так что несмотря на то, что ты прав в общем — слишком легко нарваться на "тепличный" случай, когда можно даже на равенство сравнивать.

J>Т.е. если у тебя в программе есть поле ввода, откуда ты читаешь число с плавающей запятой, то 180 всегда будет точно 180 (буду рад услышать аргументацию, почему оно не может быть таковым), а вот с пи тебе придется туго.

J>Естественно, если ты над этими 180 будешь потом изгаляться, в результате у тебя в общем случае получится не точно 180, но если ты берешь как есть — оно будет точным, и в этом нет никакой разницы с целыми числами.
J>Поправь меня, если это не так.

Ну кто бы спорил, я подтвержу. Только это не единственный вывод, который тут можно и нужно делать.
The God is real, unless declared integer.
Re: Смерть булевским аргументам!
От: Vain Россия google.ru
Дата: 12.09.09 21:15
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Robert C. Martin's Clean Code Tip #12: Eliminate Boolean Arguments

J>http://www.informit.com/articles/article.aspx?p=1392524
Хороший пример ССЗБ
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[14]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 13.09.09 01:16
Оценка:
Здравствуйте, netch80, Вы писали:

N>Я утверждал совсем не это, а то, что


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

J>>Насчет значений с плавающей запятой — есть радикальная разница в представлении 180 и M_PI: 180 всегда представлена точно, а пи так представлена быть не может в принципе, и ты всегда будешь иметь дело с обрезаниями.


N>Угу. Только вот я для проверки аккуратности плавучки нарисовал маленький кусочек кода:


N>
N>  double v1 = M_PI;
N>  double v2 = asin(1) * 2;
N>  double v3 = acos(-1);
N>


N>и как ты думаешь, что он мне выдал? он мне выдал все три равенства. Фря/7.2/i386.

N>Так что несмотря на то, что ты прав в общем — слишком легко нарваться на "тепличный" случай, когда можно даже на равенство сравнивать.

Я думаю, ты сам понимаешь, что это все — прогулки по саду граблей.
Вот пример оных:
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18
Здесь, оно, конечно, действительно тепличный случай, с точными коэффициентами и умножением на 2 (когда в представлении меняется только экспонента, а мантисса остается той же самой). Но, скажем, для углов типа пи/3 (которые все еще точны в градусной мере), мне кажется, уже никаких гарантий дать нельзя.

N>Ну кто бы спорил, я подтвержу. Только это не единственный вывод, который тут можно и нужно делать.

Пис, браза!
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[12]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 13.09.09 01:24
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

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

J>>Иди почитай где-нть про сравнение чисел с плавающей запятой на равенство, в сети море информации на эту тему....
MC>Вот ведь как — достаточно обвинить оппонента в невежестве и его сообщения можно не читать. Да?

Ну вот если ты все мои сообщения в этой ветке прочитал, ты все еще продолжаешь настаивать, что сравнивать с пи — это хорошая идея?
Вот замечательный пример фейерверков, которые бывают при сравнении плавающих чисел (там вообще аргументы — единички, все еще проще и нагляднее):
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18

Если ты все это уже знал и все равно ответил то, что ответил — ну, значит, я не понял, что ты имеешь в виду и как ты собираешься от этих эффектов уходить, прошу прощения.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[13]: Смерть булевским аргументам!
От: Курилка Россия http://kirya.narod.ru/
Дата: 13.09.09 04:23
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Вот замечательный пример фейерверков, которые бывают при сравнении плавающих чисел (там вообще аргументы — единички, все еще проще и нагляднее):

J>http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18
Я так понимаю имелоь в виду всёж http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17?
Re[12]: Смерть булевским аргументам!
От: wallaby  
Дата: 13.09.09 05:01
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

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

J>>Иди почитай где-нть про сравнение чисел с плавающей запятой на равенство, в сети море информации на эту тему....
MC>Вот ведь как — достаточно обвинить оппонента в невежестве и его сообщения можно не читать. Да?

Короче, при операциях с плавающей запятой правильный путь — интервальные вычисления — http://interval.louisiana.edu/preprints/survey.pdf
---
The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true
Re[14]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 13.09.09 05:58
Оценка:
Здравствуйте, Курилка, Вы писали:

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


J>>Вот замечательный пример фейерверков, которые бывают при сравнении плавающих чисел (там вообще аргументы — единички, все еще проще и нагляднее):

J>>http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18
К>Я так понимаю имелоь в виду всёж http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17?

ну, 17-й очевиден и его все знают (я так думаю), а 18-й гораздо прикольнее, согласись, и больше подходит к примеру netch80.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[15]: Смерть булевским аргументам!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 13.09.09 06:16
Оценка:
Здравствуйте, jazzer, Вы писали:

N>>и как ты думаешь, что он мне выдал? он мне выдал все три равенства. Фря/7.2/i386.

N>>Так что несмотря на то, что ты прав в общем — слишком легко нарваться на "тепличный" случай, когда можно даже на равенство сравнивать.
J>Я думаю, ты сам понимаешь, что это все — прогулки по саду граблей.

Я-то понимаю. Я на подобные грабли наступал регулярно и в более извращённой форме. Но на практике постоянно встречаешь ситуации, когда заведомо грабельные решения работают, потому что именно в данном случае грабли не встретились. Вот это — неприятно.

J>Вот пример оных:

J>http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18

Ну это уже вообще-то диверсия компилятора. Даже если стандарт такое допускает, я бы за такое написание компилятора бил ногами.

J>Здесь, оно, конечно, действительно тепличный случай, с точными коэффициентами и умножением на 2 (когда в представлении меняется только экспонента, а мантисса остается той же самой). Но, скажем, для углов типа пи/3 (которые все еще точны в градусной мере), мне кажется, уже никаких гарантий дать нельзя.


Это ты про радианы и попытки на их основании вычислить точный угол? Ну я как раз такого пути не предлагаю — точный угол надо определять только по градусам.

N>>Ну кто бы спорил, я подтвержу. Только это не единственный вывод, который тут можно и нужно делать.

J>Пис, браза! :beer:

дык ёлы-палы:)
The God is real, unless declared integer.
Re[13]: Смерть булевским аргументам!
От: igna Россия  
Дата: 13.09.09 06:41
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Так и представил себе пользователя, вбивающего в окошечко "угод" пи с точностью до хз какого знака после запятой ...


Ну, собственно, в первом моем сообщении в этой теме я сразу написал:

... это преобразование нужно выполнять только при вводе информации от пользователя, внутри программа должна иметь дело только с радианами.

http://rsdn.ru/forum/philosophy/3532246.1.aspx

Re[15]: Смерть булевским аргументам!
От: Курилка Россия http://kirya.narod.ru/
Дата: 13.09.09 08:27
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Курилка, Вы писали:


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


J>>>Вот замечательный пример фейерверков, которые бывают при сравнении плавающих чисел (там вообще аргументы — единички, все еще проще и нагляднее):

J>>>http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18
К>>Я так понимаю имелоь в виду всёж http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17?

J>ну, 17-й очевиден и его все знают (я так думаю), а 18-й гораздо прикольнее, согласись, и больше подходит к примеру netch80.


только единичек там я не вижу.
Re[16]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 13.09.09 11:58
Оценка:
Здравствуйте, Курилка, Вы писали:

J>>ну, 17-й очевиден и его все знают (я так думаю), а 18-й гораздо прикольнее, согласись, и больше подходит к примеру netch80.


К>только единичек там я не вижу.


единички выделены:
#include <cmath>
 
 void foo(double x, double y)
 {
   if (cos(x) != cos(y)) {
     std::cout << "Huh?!?\n"; // ← you might end up here when x == y!!
   }
 }
 
 int main()
 {
   foo(1.0, 1.0);
   return 0;
 }
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Смерть булевским аргументам!
От: _pk_sly  
Дата: 13.09.09 21:19
Оценка:
Здравствуйте, wallaby, Вы писали:

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


J>>Robert C. Martin's Clean Code Tip #12: Eliminate Boolean Arguments

J>>http://www.informit.com/articles/article.aspx?p=1392524

W>Так много слов для одной простой мысли:

W>Вместо одной функции с булевым аргументом часто правильнее использовать две функции.

а я не согласен.

там ниже пишут про функции с WinAPI с пятью параметрами TRUE — что, правильнее сделать 32 функции? — это бред.

правильно — делать правильную функциональную декомпозицию.
Re[13]: Смерть булевским аргументам!
От: Mr.Cat  
Дата: 13.09.09 21:45
Оценка:
Здравствуйте, jazzer, Вы писали:
J>Ну вот если ты все мои сообщения в этой ветке прочитал, ты все еще продолжаешь настаивать, что сравнивать с пи — это хорошая идея?
Я продолжаю настаивать, что градусы не лучше радианов.

J>Вот замечательный пример фейерверков, которые бывают при сравнении плавающих чисел (там вообще аргументы — единички, все еще проще и нагляднее):

J>http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18
Восхитительно. Как видишь, от погрешности вычислений ты не защищен даже в простейших случаях и даже если у тебя входные данные точно представимы в соответствующих типах данных. Ты все еще настаиваешь, что 180.0 лучше, чем M_PI?

Я соглашусь, что градусы хороши как минимум в 2 случаях:
1. В качестве формата входных/выходных данных — когда они вводятся пользователем или выдаются пользователю — это то, о чем ты пишешь здесь: http://rsdn.ru/forum/philosophy/3535040.1.aspx
Автор: jazzer
Дата: 12.09.09
. И то:
1.1 Только за счет наличия особых точек: 45, 90, 180, ну и т.п.
1.2 Не всегда, т.к. иногда лучше вместо особой точки сделать "отдельную кнопку", например, выделить в меню 2 "поворота на пи-пополам" и один "поворот на угол".
1.3 Нужно задуматься, о предметной области и откуда пользователь берет вводимые значения — из головы или, скажем, из вывода какого-нибудь символьного пакета, который выдает ему значения в формате "пи-пополам плюс е-в-кубе".
2. Когда возможны целочисленные вычисления. Тогда угол, наверное, удобнее представлять градусами, чем какими-нибудь процентами от пи.

В остальных случаях радианы ничуть не хуже.
Re[4]: По поводу финансовых программ
От: fmiracle  
Дата: 14.09.09 05:05
Оценка:
Здравствуйте, igna, Вы писали:

J>>То же, кстати, относится к доброй половине финансовых программ, где цены, вроде как, не целые, но из лучше хранить как целые или как пару целых.


I>Кстати, а что, все же есть финансовые программы, которые хранят цены как float? Никогда подобными вещами не занимался, но вроде это расхожий пример неправильного выбора типа.


Все зависит от конкретной задачи.
Если допустима погрешность — то почему бы и нет?

А погрешность полностью недопустима только в программах вещущих учет денег в той или иной форме. Потому что несовпадение общей суммы и подсуммы любой части однозначно является некорректным поведением.

Для программ же анализа финансовых данных, погрешность вополне может быть допустима.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Re[3]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 14.09.09 05:46
Оценка:
Здравствуйте, _pk_sly, Вы писали:

__>там ниже пишут про функции с WinAPI с пятью параметрами TRUE — что, правильнее сделать 32 функции? — это бред.

Нет, просто вместо булевских параметров сделать енумы.

__>правильно — делать правильную функциональную декомпозицию.

"правильно — делать правильно" — с этим, наверное, все согласны
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Смерть булевским аргументам!
От: mogadanez Чехия  
Дата: 14.09.09 08:47
Оценка: +1
Здравствуйте, jazzer, Вы писали:

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


__>>там ниже пишут про функции с WinAPI с пятью параметрами TRUE — что, правильнее сделать 32 функции? — это бред.

J>Нет, просто вместо булевских параметров сделать енумы.

интересный вывод...

дядя Боб пишет что основная проьлема булевых аргументов

Boolean arguments loudly declare that the function does more than one thing


енумы в этом смысле ничуть не лучше.
Re[5]: Смерть булевским аргументам!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 14.09.09 09:02
Оценка:
Здравствуйте, mogadanez, Вы писали:

__>>>там ниже пишут про функции с WinAPI с пятью параметрами TRUE — что, правильнее сделать 32 функции? — это бред.

J>>Нет, просто вместо булевских параметров сделать енумы.
M>интересный вывод...
M>дядя Боб пишет что основная проьлема булевых аргументов
M>

M>Boolean arguments loudly declare that the function does more than one thing

M>енумы в этом смысле ничуть не лучше.

Любые неколичественные аргументы в этом смысле ничуть не лучше.

Вот пример из моих краёв. Ожидание сигнала по условной переменной делается в ядре FreeBSD4 (для простоты беру её) вызовом tsleep(var, prio), при этом прерываемость межзадачным сигналом задаётся битовым флажком PCATCH в prio, например:

tsleep(&softc->s_in, TTIPRI|PCATCH);

В Linux это же делается другой функцией — вместо sleep_on() вызывается sleep_on_interruptible(). Хотя на уровне шедулера их код совпадает на 90%, и всё, что внутри отличается в этом случае — простановка другого значения состояния задачи (TASK_UNINTERRUPTIBLE или TASK_INTERRUPTIBLE). Оптимизация в одну функцию с флагом напрашивается сама, но её не делают намеренно.
The God is real, unless declared integer.
Re[5]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 14.09.09 09:12
Оценка:
Здравствуйте, mogadanez, Вы писали:

__>>>там ниже пишут про функции с WinAPI с пятью параметрами TRUE — что, правильнее сделать 32 функции? — это бред.

J>>Нет, просто вместо булевских параметров сделать енумы.

M>дядя Боб пишет что основная проьлема булевых аргументов

M>

M>Boolean arguments loudly declare that the function does more than one thing

M>енумы в этом смысле ничуть не лучше.

Ну в этом смысле да, но я лично смысла в "этом смысле" не вижу, и тут я с ним не согласен совершенно.
Одно дело, когда аргумент исползуется для переключения между двумя совершенно разными действиями типа сплясатьЖигуИлиСваритьСуп(bool), а другое — когда действие по сути одно и то же, а аргументы просто служат в качестве опций и тонкой настройки.
В первом случае — очевидно, нужно разбивать на две функции.
Во втором — нужно просто дать аргументам адекватные имена и типы и оставить одну функцию.
Вызов его функции rotate(30, true) совершенно нечитабелен, в то время как вызов rotate(30, Radians) и rotate(30, Degrees) совершенно однозначен и понятен без дополнительных пояснений, и я не вижу причин, по которым надо бы предпочесть этой одной функции две без этого дополнительного параметра. Особенно если таких аргументов много — получится, что надо делать 32 функции, что, очевидно, бред.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[14]: Смерть булевским аргументам!
От: jazzer Россия Skype: enerjazzer
Дата: 14.09.09 11:28
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

MC>Я продолжаю настаивать, что градусы не лучше радианов.

MC>Я соглашусь, что градусы хороши как минимум в 2 случаях:
MC>В остальных случаях радианы ничуть не хуже.

Ну наконец-то
Несколько противоречиво, но все равно
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.