Сравнение двух double
От: XJess  
Дата: 01.10.10 16:34
Оценка:
Добрый вечер всем!
Есть такой вот конструктор в классе (написан не мной), который, видимо, радианы переводит в градусы, минуты и секунды. Никак не могу понять, что товарищ хотел сказать строчкой if (_sec >= 59.999999)... Что, например, будет, если у меня _sec будет 59.9999999, тогда условие выполнится и переменная обнулится... Кстати, в C# можно так запросто double сравнивать с помощью >=? Вот в С++ лучше не стоит... Вообщем, что скажете? Это нормальный код? Как, кстати, правильно сравнивать Double-ы? С помощью Double.CompareTo?


public class Angle
    {
        double _radianValue;
        int _sign;
        int _deg;
        int _min;
        double _sec;

        public Angle(double radianValue)
        {
            _radianValue = radianValue;
            double degValue = _radianValue * 180 / Math.PI;
            _sign = Math.Sign(degValue);
            double ddeg = Math.Abs(degValue);
            _deg = (int)Math.Floor(ddeg);
            double dmin = (ddeg - Math.Floor(ddeg)) * 60;
            _min = (int)Math.Floor(dmin);
            _sec = (dmin - Math.Floor(dmin)) * 60;
            if (_sec >= 59.999999)
            {
                _sec = 0;
                _min++;
                if (_min >= 60)
                {
                    _min = 0;
                    _deg++;
                }
            }
        }
...

 }
Re: Сравнение двух double
От: Lloyd Россия  
Дата: 01.10.10 16:39
Оценка: 5 (2)
Здравствуйте, XJess, Вы писали:

XJ>Кстати, в C# можно так запросто double сравнивать с помощью >=?


Да, можно.

XJ>Вот в С++ лучше не стоит...


С "==" не путаете?

XJ>Вообщем, что скажете? Это нормальный код? Как, кстати, правильно сравнивать Double-ы? С помощью Double.CompareTo?


CompareTo внутрях зовет все тот же "<", по крайней мере reflector показывает "<".
Re[2]: Сравнение двух double
От: XJess  
Дата: 01.10.10 18:50
Оценка:
Здравствуйте, Lloyd, Вы писали:

XJ>>Вот в С++ лучше не стоит...


L>С "==" не путаете?


Может, я что-то и путаю... Но тут же и равенство тоже проверяется...
Re[3]: Сравнение двух double
От: hardcase Пират http://nemerle.org
Дата: 02.10.10 14:23
Оценка: +1
Здравствуйте, XJess, Вы писали:

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


XJ>>>Вот в С++ лучше не стоит...


L>>С "==" не путаете?


XJ>Может, я что-то и путаю... Но тут же и равенство тоже проверяется...


Плохо строго сравнивать на равенство (неравенство) два числа с плавающей запятой. Все остальные случаи вполне имеют право на жизнь.
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Сравнение двух double
От: Nikolay_P_I  
Дата: 02.10.10 20:21
Оценка:
Здравствуйте, XJess, Вы писали:

XJ>Есть такой вот конструктор в классе (написан не мной), который, видимо, радианы переводит в градусы, минуты и секунды. Никак не могу понять, что товарищ хотел сказать строчкой if (_sec >= 59.999999)... Что, например, будет, если у меня _sec будет 59.9999999, тогда условие выполнится и переменная обнулится...


Это частый прием. Переводится на русский примерно как "результат со всеми значащими знаками больше-равно 60". Из криминала здесь только встроенный magic number.
60 как double оно, конечно, не ровно 60, но отличия от ровно 60 там в далеких знаках. Только я бы просто > без = использовал.
Re: Сравнение двух double
От: andy1618 Россия  
Дата: 06.10.10 03:42
Оценка:
Здравствуйте, XJess, Вы писали:

XJ>Добрый вечер всем!

XJ>Никак не могу понять, что товарищ хотел сказать строчкой if (_sec >= 59.999999)...

Судя по всему, автор кода напоролся на случай, когда значение секунд (оно, в отличие от градусов и минут, вещественное!) из-за погрешности вычислений, оказывается >= 60.0
Вот и вставил такую не очень красивую проверку.

Совет: напишите на этот конструктор юнит-тесты — в том числе, чтобы этот if срабатывал.
Ну а потом уже можно попробовать переписать этот кусочек более красиво.

Про сравнение даблов — вам уже в другой ветке много полезного отписали:
http://www.rsdn.ru/forum/cpp/3981338.aspx
Автор: XJess
Дата: 01.10.10

Правда, в нашем случае речь идёт про конкретную предметную область (координаты), поэтому вполне уместно вручную задать какую-то фиксированную абсолютную погрешность вычислений.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.