Информация об изменениях

Сообщение Re[6]: Как провести вычисление только в рамках типа float, а от 02.12.2016 7:18

Изменено 02.12.2016 7:26 oziro

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

S>Угу, сравнивать double могут не только лишь все.


Ага, заморочки присутствуют.

Вообще, у меня
        static bool Equal(double a, double b)
        {            
            return Equal(a, b, 16); // вышеупомянутся Equal()
        }


используется по дефолту во всех местах.

А для нуля — особая ситуация.

        bool IsZero(double a, double estimateValue)
        {
            double epsilon = 16 * DBL_EPSILON * Math.Abs(estimateValue);
            return Math.Abs(a) <= epsilon;
        }


Т.к. в одной ситуации сравнение 1e-320 c нулем должно дать True, а другом False, в зависимости от самих вычислений. Поэтому я передаю в функцию оценочное значение. (на самом деле, возьмем число 1e-300, ибо 1e320 вообще в double не умещается)

и тогда
    False == IsZero(1e-300, 1e-290); // 1e-300 != 0.  (1e-290 - напрмер, одно из значений, участвующих в вычислениях)
    True == IsZero(1e-300, 1e-50); // 1e-300 == 0 (1e-50 - аналогично, примерное значение, участвующее в вычислених)


Короче, с нулем надо сравнивать с указанной оценкой — это, наверно, всегда. Ну, или делать умолчание на диапазон типа 1e-9 .. 1e9 , но всегда понимать, что тогда оно не будет работать во многих случаях, а это верные грабли, потому что забудут и будет использовать. Поэтому IsZero с доп. параметром-оценкой.

UPD Я, конечно, ошибся. 1e-320 может быть представлено в double
Re[6]: Как провести вычисление только в рамках типа float, а
Здравствуйте, Sinix, Вы писали:

S>Угу, сравнивать double могут не только лишь все.


Ага, заморочки присутствуют.

Вообще, у меня
        static bool Equal(double a, double b)
        {            
            return Equal(a, b, 16); // вышеупомянутся Equal()
        }


используется по дефолту во всех местах.

А для нуля — особая ситуация.

        bool IsZero(double a, double estimateValue)
        {
            double epsilon = 16 * DBL_EPSILON * Math.Abs(estimateValue);
            return Math.Abs(a) <= epsilon;
        }


Т.к. в одной ситуации сравнение 1e-320 c нулем должно дать True, а другом False, в зависимости от самих вычислений. Поэтому я передаю в функцию оценочное значение.

и тогда
    False == IsZero(1e-320, 1e-310); // 1e-320 != 0.  (1e-310 - напрмер, одно из значений, участвующих в вычислениях)
    True == IsZero(1e-320, 1e-100); // 1e-320 == 0 (1e-100 - аналогично, примерное значение, участвующее в вычислених)


Короче, с нулем надо сравнивать с указанной оценкой — это, наверно, всегда. Ну, или делать умолчание на диапазон типа 1e-9 .. 1e9 , но всегда понимать, что тогда оно не будет работать во многих случаях, а это верные грабли, потому что забудут и будет использовать. Поэтому IsZero с доп. параметром-оценкой.

UPD Я, конечно, ошибся. 1e-320 может быть представлено в double Fixed