/* ********************************************************************* This source file is a part of the standard library of Scol For the latest info, see http://www.scolring.org Copyright (c) 2013 Stephane Bisaro aka Iri. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ********************************************************************* */ /* * Standard functions for floatting point numbers * See http://redmine.scolring.org/projects/tutorials/wiki/Scol_usage * for more informations */ /*! \file float.pkg * \author Scol team * \version 0.1 * \copyright GNU Lesser General Public License 2.0 or later * \brief Scol Standard Library - Floatting point numbers API * * \details This API provides some functions to manipulate the floatting point numbers (F) * **/ var STD_LOOP_EPSILON = 0.000001;; /*! \brief Get the 'epsilon' to compare deux floating point numbers * * \details By default, this value is 0.000001 * * \ingroup std_float * Prototype : : fun [] F * \return F : the current epsilon **/ fun std_fEpsilonGet ()= STD_LOOP_EPSILON;; /*! \brief Set the 'epsilon' to compare deux floating point numbers * * \details By default, this value is 0.000001 * * \ingroup std_float * Prototype : : fun [F] F * \param F : a new 'epsilon' * \return F : the same value **/ fun std_fEpsilonSet (f)= set STD_LOOP_EPSILON = f;; /*! \brief Return if a float number is near at zero (depending of epsilon) * * \ingroup std_float * \see std_fEpsilonSet * \see std_fEpsilonGet * * Prototype : : fun [F] I * \param F : value to test * \return I : 1 if zero else 0 **/ fun std_fIsZero (f)= STD_LOOP_EPSILON >. absf f;; /*! \brief Compare two float numbers (depending of epsilon) * * \ingroup std_float * \see std_fEpsilonSet * \see std_fEpsilonGet * * Prototype : : fun [F F] I * \param F : a float number * \param F : another float number * \return I : 1 if they are equals else 0 **/ fun std_fCmp (f1, f2)= STD_LOOP_EPSILON >. absf (f1 -. f2);; /*! \brief Return if a a float number in a range * * \ingroup std_float * Prototype : : fun [F F F] I * \param F : a float number * \param F : the bottom of the range (start) * \param F : the top of the range (end) * \return I : 1 if success, 0 if fail or nil if error (start > end) **/ fun std_fInRange (f, startf, endf)= if (startf >. endf) then nil else if ((startf >. f) || (endf <. f)) then 0 else 1;; /*! \brief Clamp a float number in a range * * * \ingroup std_float * Prototype : : fun [F F F] F * \param F : a float number * \param F : the bottom of the range (start) * \param F : the top of the range (end) * \return F : the float number clamped or nil if error (start > end) **/ fun std_fClamp (f, startf, endf)= if (startf >. endf) then nil else if (startf >. f) then startf else if (endf <. f) then endf else f;; /*! \brief Return the entire and the decimal parts of a float number * * \ingroup std_float * \remark the decimal part can be rounded. * * Prototype : : fun [F] [I F] * \param F : a float number * * \return [I F] : the tuple **/ fun std_fIntDec (f)= let ftoi f -> i in [i f-.itof i];; /*! \brief Perform a division between two float numbers * The function returns a tuple : the result, the entire and the decimal parts of the result. * *
 _fooS sprintf "%f %i %f" std_fDivide 10.25 5.0;	// 2,050000 2 0,050000
 
* * \remark the decimal part can be rounded. * * \ingroup std_float * Prototype : : fun [F] [F I F] * \param F : a float number * * \return [F I F] : the result and the entire and decimal parts of the result **/ fun std_fDivide (f1, f2)= let f1/.f2 -> r in let ftoi (f1/.f2) -> i in let (f1-.(f2*.(itof i)))/.f2 -> d in [r i d];; /*! \brief Return if two float vectors are equals * * \ingroup std_float * * * Prototype: fun [[F F F] [F F F]] I * * \param [F F F] : first float vector * \param [F F F] : second float vector * * \return I : 1 if are equuals else 0 * \remark The float number are compared with an 'epsilon'. **/ fun std_vectorIsEqualF (v1, v2)= let v1 -> [x1 y1 z1] in let v2 -> [x2 y2 z2] in (std_fCmp x1 x2) && (std_fCmp y1 y2) && (std_fCmp z1 z2);;