// Copyright (C) 2013 panacoran <panacoran@users.sourceforge.jp>
// 
// This program is part of Protra.
//
// Protra is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
// 
// $Id$

using System;

namespace Protra.Lib
{
    /// <summary>
    /// 浮動小数点数の比較を行うクラス
    /// </summary>
    public class FloatComparers
    {
        /// <summary>
        /// doubleを比較する。
        /// </summary>
        /// <param name="lhs">左辺</param>
        /// <param name="rhs">右辺</param>
        /// <returns>左辺と右辺が等しければ0を、左辺が右辺より小さければ-1を、それ以外は1を返す。</returns>
        public static int Compare(double lhs, double rhs)
        {
            const double epsilon = 1e-12;
            var diff = Math.Abs(lhs - rhs);
            if (diff <= epsilon || diff <= Math.Max(Math.Abs(lhs), Math.Abs(rhs)) * epsilon)
                return 0;
            if (lhs < rhs)
                return -1;
            return 1;
        }

        /// <summary>
        /// doubleの等値比較をする。
        /// </summary>
        /// <param name="lhs">左辺</param>
        /// <param name="rhs">右辺</param>
        /// <returns>左辺と右辺が等しければtrueを、そうでなければfalseを返す。</returns>
        public static bool Equal(double lhs, double rhs)
        {
            return Compare(lhs, rhs) == 0;
        }

        /// <summary>
        /// floatを比較する。
        /// </summary>
        /// <param name="lhs">左辺</param>
        /// <param name="rhs">右辺</param>
        /// <returns>左辺と右辺が等しければ0を、左辺が右辺より小さければ-1を、それ以外は1を返す。</returns>
        public static int Compare(float lhs, float rhs)
        {
            const float epsilon = 1e-5f;
            var diff = Math.Abs(lhs - rhs);
            if (diff <= epsilon || diff <= Math.Max(Math.Abs(lhs), Math.Abs(rhs)) * epsilon)
                return 0;
            if (lhs < rhs)
                return -1;
            return 1;
        }

        /// <summary>
        /// floatの等値比較をする。
        /// </summary>
        /// <param name="lhs">左辺</param>
        /// <param name="rhs">右辺</param>
        /// <returns>左辺と右辺が等しければtrueを、そうでなければfalseを返す。</returns>
        public static bool Equal(float lhs, float rhs)
        {
            return Compare(lhs, rhs) == 0;
        }
    }
}