[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[certi-cvs] certi libCERTI/FedTime.cc include/fedtime.hh RT...
From: |
certi-cvs |
Subject: |
[certi-cvs] certi libCERTI/FedTime.cc include/fedtime.hh RT... |
Date: |
Tue, 06 May 2008 13:36:19 +0000 |
CVSROOT: /sources/certi
Module name: certi
Changes by: Eric NOULARD <erk> 08/05/06 13:36:19
Modified files:
libCERTI : FedTime.cc
include : fedtime.hh
RTIA : TimeManagement.cc
Log message:
Fix bug #23090 : UpdateAttributeValues throws InvalidFederationTime
We should use consistent epsilon value and carefully compare floating
point numbers (for time)
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/certi/libCERTI/FedTime.cc?cvsroot=certi&r1=3.12&r2=3.13
http://cvs.savannah.gnu.org/viewcvs/certi/include/fedtime.hh?cvsroot=certi&r1=3.8&r2=3.9
http://cvs.savannah.gnu.org/viewcvs/certi/RTIA/TimeManagement.cc?cvsroot=certi&r1=3.35&r2=3.36
Patches:
Index: libCERTI/FedTime.cc
===================================================================
RCS file: /sources/certi/certi/libCERTI/FedTime.cc,v
retrieving revision 3.12
retrieving revision 3.13
diff -u -b -r3.12 -r3.13
--- libCERTI/FedTime.cc 7 Apr 2008 15:08:27 -0000 3.12
+++ libCERTI/FedTime.cc 6 May 2008 13:36:18 -0000 3.13
@@ -19,7 +19,7 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// ----------------------------------------------------------------------------
-
+#include <math.h>
#include "certi.hh"
#include "fedtime.hh"
@@ -63,6 +63,87 @@
return const_cast<FedTime &>(time).isPositiveInfinity() == RTI::RTI_TRUE ;
}
+/*
+ fcmp
+ Copyright (c) 1998-2000 Theodore C. Belding
+ University of Michigan Center for the Study of Complex Systems
+ <mailto:address@hidden>
+ <http://fcmp.sourceforge.net>
+
+ This file is part of the fcmp distribution. fcmp is free software;
+ you can redistribute and modify it under the terms of the GNU Library
+ General Public License (LGPL), version 2 or later. This software
+ comes with absolutely no warranty. See the file COPYING for details
+ and terms of copying.
+
+ Description:
+
+ Knuth's floating point comparison operators, from:
+ Knuth, D. E. (1998). The Art of Computer Programming.
+ Volume 2: Seminumerical Algorithms. 3rd ed. Addison-Wesley.
+ Section 4.2.2, p. 233. ISBN 0-201-89684-2.
+
+ Input parameters:
+ x1, x2: numbers to be compared
+ epsilon: determines tolerance
+
+ epsilon should be carefully chosen based on the machine's precision,
+ the observed magnitude of error, the desired precision, and the
+ magnitude of the numbers to be compared. See the fcmp README file for
+ more information.
+
+ This routine may be used for both single-precision (float) and
+ double-precision (double) floating-point numbers.
+
+ Returns:
+ -1 if x1 < x2
+ 0 if x1 == x2
+ 1 if x1 > x2
+*/
+
+inline int
+fcmp(double x1,double x2, double epsilon)
+{
+ int exponent;
+ double delta;
+ double difference;
+
+ /* Get exponent(max(fabs(x1), fabs(x2))) and store it in exponent. */
+
+ /* If neither x1 nor x2 is 0, */
+ /* this is equivalent to max(exponent(x1), exponent(x2)). */
+
+ /* If either x1 or x2 is 0, its exponent returned by frexp would be 0, */
+ /* which is much larger than the exponents of numbers close to 0 in */
+ /* magnitude. But the exponent of 0 should be less than any number */
+ /* whose magnitude is greater than 0. */
+
+ /* So we only want to set exponent to 0 if both x1 and */
+ /* x2 are 0. Hence, the following works for all x1 and x2. */
+
+ frexp(fabs(x1) > fabs(x2) ? x1 : x2, &exponent);
+
+ /* Do the comparison. */
+
+ /* delta = epsilon * pow(2, exponent) */
+
+ /* Form a neighborhood around x2 of size delta in either direction. */
+ /* If x1 is within this delta neighborhood of x2, x1 == x2. */
+ /* Otherwise x1 > x2 or x1 < x2, depending on which side of */
+ /* the neighborhood x1 is on. */
+
+ delta = ldexp(epsilon, exponent);
+
+ difference = x1 - x2;
+
+ if (difference > delta)
+ return 1; /* x1 > x2 */
+ else if (difference < -delta)
+ return -1; /* x1 < x2 */
+ else /* -delta <= difference <= delta */
+ return 0; /* x1 == x2 */
+}
+
const char *infinity_str = "+inf" ;
} // anonymous namespace
@@ -89,24 +170,31 @@
//{
//}
+const double RTIfedTime::epsilon = std::numeric_limits<double>::epsilon();
+
+int
+RTIfedTime::fcmp(const double x1, const double x2) {
+ return ::fcmp(x1,x2,RTIfedTime::epsilon);
+}
+
// ----------------------------------------------------------------------------
// RTIfedTime
RTIfedTime::RTIfedTime()
: _fedTime(0),
_zero(0),
- _epsilon(std::numeric_limits<double>::epsilon()),
+ _epsilon(RTIfedTime::epsilon),
_positiveInfinity(std::numeric_limits<double>::infinity()) { }
RTIfedTime::RTIfedTime(const RTI::Double &time)
: _fedTime(time),
_zero(0),
- _epsilon(std::numeric_limits<double>::epsilon()),
+ _epsilon(RTIfedTime::epsilon),
_positiveInfinity(std::numeric_limits<double>::infinity()) { }
RTIfedTime::RTIfedTime(const FedTime &time)
: _fedTime(rft(time).getTime()),
_zero(0),
- _epsilon(std::numeric_limits<double>::epsilon()),
+ _epsilon(RTIfedTime::epsilon),
_positiveInfinity(std::numeric_limits<double>::infinity()) { }
// ----------------------------------------------------------------------------
@@ -228,7 +316,7 @@
else if (is_infinity(*this))
return RTI::RTI_FALSE ;
else
- return RTI::Boolean(_fedTime <= rft(time)._fedTime);
+ return RTI::Boolean(::fcmp(_fedTime, rft(time)._fedTime, _epsilon) <=
0);
}
// ----------------------------------------------------------------------------
@@ -239,7 +327,7 @@
if (is_infinity(*this))
return RTI::RTI_FALSE ;
else
- return RTI::Boolean(is_infinity(time) || _fedTime < rft(time)._fedTime);
+ return RTI::Boolean(is_infinity(time) || ::fcmp(_fedTime,
rft(time)._fedTime, _epsilon) < 0);
}
// ----------------------------------------------------------------------------
@@ -252,7 +340,7 @@
else if (is_infinity(time))
return RTI::RTI_FALSE ;
else
- return RTI::Boolean(_fedTime >= rft(time)._fedTime);
+ return RTI::Boolean(::fcmp(_fedTime, rft(time)._fedTime, _epsilon) >=
0);
}
// ----------------------------------------------------------------------------
@@ -263,7 +351,7 @@
if (is_infinity(time))
return RTI::RTI_FALSE ;
else
- return RTI::Boolean(is_infinity(*this) || _fedTime >
rft(time)._fedTime);
+ return RTI::Boolean(is_infinity(*this) || ::fcmp(_fedTime,
rft(time)._fedTime, _epsilon) > 0);
}
// ----------------------------------------------------------------------------
@@ -276,7 +364,7 @@
else if (is_infinity(*this) || is_infinity(time))
return RTI::RTI_FALSE ;
else
- return RTI::Boolean(_fedTime == rft(time)._fedTime);
+ return RTI::Boolean(::fcmp(_fedTime, rft(time)._fedTime, _epsilon) ==
0);
}
// ----------------------------------------------------------------------------
@@ -300,7 +388,7 @@
RTIfedTime::operator==(const Double &time) const
throw (RTI::InvalidFederationTime)
{
- return RTI::Boolean(!is_infinity(*this) && _fedTime == time);
+ return RTI::Boolean(!is_infinity(*this) && ::fcmp(_fedTime, time,
_epsilon) == 0);
}
// ----------------------------------------------------------------------------
@@ -308,7 +396,7 @@
RTIfedTime::operator!=(const FedTime &time) const
throw (RTI::InvalidFederationTime)
{
- return RTI::Boolean(!(*this == time));
+ return RTI::Boolean(::fcmp(_fedTime, rft(time)._fedTime, _epsilon) != 0);
}
// ----------------------------------------------------------------------------
@@ -316,7 +404,7 @@
RTIfedTime::operator!=(const Double &time) const
throw (RTI::InvalidFederationTime)
{
- return RTI::Boolean(is_infinity(*this) || _fedTime != time);
+ return RTI::Boolean(is_infinity(*this) || ::fcmp(_fedTime, time, _epsilon)
!= 0);
}
// ----------------------------------------------------------------------------
Index: include/fedtime.hh
===================================================================
RCS file: /sources/certi/certi/include/fedtime.hh,v
retrieving revision 3.8
retrieving revision 3.9
diff -u -b -r3.8 -r3.9
--- include/fedtime.hh 26 Sep 2007 14:14:46 -0000 3.8
+++ include/fedtime.hh 6 May 2008 13:36:19 -0000 3.9
@@ -1,5 +1,5 @@
// HLA 1.3 Header "fedtime.hh"
-// $Id: fedtime.hh,v 3.8 2007/09/26 14:14:46 erk Exp $
+// $Id: fedtime.hh,v 3.9 2008/05/06 13:36:19 erk Exp $
#ifndef HLA_FEDTIME_HH
#define HLA_FEDTIME_HH
@@ -15,6 +15,10 @@
class CERTI_EXPORT RTIfedTime : public RTI::FedTime
{
public:
+
+ static const double epsilon;
+ static int fcmp(const double x1, const double x2);
+
RTIfedTime();
RTIfedTime(const RTI::Double &);
RTIfedTime(const RTI::FedTime &);
@@ -131,4 +135,4 @@
#endif // HLA_FEDTIME_HH
-// $Id: fedtime.hh,v 3.8 2007/09/26 14:14:46 erk Exp $
+// $Id: fedtime.hh,v 3.9 2008/05/06 13:36:19 erk Exp $
Index: RTIA/TimeManagement.cc
===================================================================
RCS file: /sources/certi/certi/RTIA/TimeManagement.cc,v
retrieving revision 3.35
retrieving revision 3.36
diff -u -b -r3.35 -r3.36
--- RTIA/TimeManagement.cc 5 May 2008 09:47:20 -0000 3.35
+++ RTIA/TimeManagement.cc 6 May 2008 13:36:19 -0000 3.36
@@ -18,7 +18,7 @@
// along with this program ; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// $Id: TimeManagement.cc,v 3.35 2008/05/05 09:47:20 erk Exp $
+// $Id: TimeManagement.cc,v 3.36 2008/05/06 13:36:19 erk Exp $
// ----------------------------------------------------------------------------
#include <config.h>
@@ -33,7 +33,6 @@
PrettyDebug D("RTIA_TM", __FILE__);
static PrettyDebug G("GENDOC",__FILE__) ;
-const double epsilon = 1.0e-6 ;
}
@@ -480,8 +479,11 @@
_type_granted_state = AFTER_TAR_OR_NER ; // will be
- if (_lookahead_courant == 0.0) {
- _lookahead_courant = epsilon ;
+ // FIXME Erk-->Pierre
+ // We were changing lookahead value to epsilon
+ // when doing zero lookahead I'd rather handle
+ // _any_ near-to-zero lookahead as ZERO_LK
+ if (0==RTIfedTime::fcmp(_lookahead_courant,0.0)) {
_type_granted_state = AFTER_TAR_OR_NER_WITH_ZERO_LK ;
}
@@ -668,26 +670,35 @@
bool
TimeManagement::testValidTime(FederationTime theTime)
{
- RTIfedTime epsilon;
-
- epsilon.setEpsilon();
+ int compareResult;
+ // FIXME Erk-->Pierre
+ // We should use RTIfedTime object and not _plain_ double
+ // value
if (_avancee_en_cours == PAS_D_AVANCEE) {
if (_type_granted_state == AFTER_TAR_OR_NER_WITH_ZERO_LK) {
- if (theTime <= _heure_courante)
+ compareResult = RTIfedTime::fcmp(theTime,_heure_courante);
+ // if theTime <= _heure_courante
+ if (compareResult==-1 || compareResult==0)
return false;
}
else { // AFTER_TAR_OR_NER or AFTER_TARA_OR_NARA
- if (theTime + epsilon.getTime() < _heure_courante +
_lookahead_courant)
+ compareResult = RTIfedTime::fcmp(theTime,_heure_courante +
_lookahead_courant);
+ // if theTime < _heure_courante + _lookahead_courant
+ if (compareResult == -1)
return false;
}
}
else {
if (_type_granted_state == AFTER_TAR_OR_NER_WITH_ZERO_LK) {
- if (theTime <= date_avancee)
+ compareResult = RTIfedTime::fcmp(theTime,date_avancee);
+ // if theTime <= date_avancee
+ if (compareResult==-1 || compareResult==0)
return false;
}
else { // AFTER_TAR_OR_NER or AFTER_TARA_OR_NARA
- if (theTime + epsilon.getTime() < date_avancee + _lookahead_courant)
+ compareResult = RTIfedTime::fcmp(theTime,date_avancee +
_lookahead_courant);
+ // if (theTime < date_avancee + _lookahead_courant)
+ if (compareResult == -1)
return false;
}
}
@@ -827,9 +838,6 @@
D.Out(pdRegister, "timeAdvanceGrant sent to federate (time = %f).",
req.getFederationTime());
- if (_lookahead_courant == epsilon)
- _lookahead_courant = 0.0 ;
-
_tick_state = TICK_NEXT; // indicate the callback was processed
comm->requestFederateService(&req);
@@ -863,8 +871,11 @@
_type_granted_state = AFTER_TAR_OR_NER ; // will be
- if (_lookahead_courant == 0.0) {
- _lookahead_courant = epsilon ;
+ // FIXME Erk-->Pierre
+ // We were changing lookahead value to epsilon
+ // when doing zero lookahead I'd rather handle
+ // _any_ near-to-zero lookahead as ZERO_LK
+ if (0==RTIfedTime::fcmp(_lookahead_courant,0.0)) {
_type_granted_state = AFTER_TAR_OR_NER_WITH_ZERO_LK ;
}
@@ -921,4 +932,4 @@
}} // namespaces
-// $Id: TimeManagement.cc,v 3.35 2008/05/05 09:47:20 erk Exp $
+// $Id: TimeManagement.cc,v 3.36 2008/05/06 13:36:19 erk Exp $
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [certi-cvs] certi libCERTI/FedTime.cc include/fedtime.hh RT...,
certi-cvs <=