Introduce additional Time units (Year, Day, Hour, Minute)
This commit is contained in:
@@ -86,13 +86,17 @@ public:
|
||||
*/
|
||||
enum Unit
|
||||
{
|
||||
S = 0, //!< second
|
||||
MS = 1, //!< millisecond
|
||||
US = 2, //!< microsecond
|
||||
NS = 3, //!< nanosecond
|
||||
PS = 4, //!< picosecond
|
||||
FS = 5, //!< femtosecond
|
||||
LAST = 6
|
||||
Y = 0, //!< year, 365 days
|
||||
D = 1, //!< day, 24 hours
|
||||
H = 2, //!< hour, 60 minutes
|
||||
MIN = 3, //!< minute, 60 seconds
|
||||
S = 4, //!< second
|
||||
MS = 5, //!< millisecond
|
||||
US = 6, //!< microsecond
|
||||
NS = 7, //!< nanosecond
|
||||
PS = 8, //!< picosecond
|
||||
FS = 9, //!< femtosecond
|
||||
LAST = 10
|
||||
};
|
||||
|
||||
inline Time &operator = (const Time &o)
|
||||
@@ -182,6 +186,10 @@ public:
|
||||
* - `ns` (nanoseconds)
|
||||
* - `ps` (picoseconds)
|
||||
* - `fs` (femtoseconds)
|
||||
* - `min` (minutes)
|
||||
* - `h` (hours)
|
||||
* - `d` (days)
|
||||
* - `y` (years)
|
||||
*
|
||||
* There can be no white space between the numerical portion
|
||||
* and the units. Any otherwise malformed string causes a fatal error to
|
||||
@@ -308,6 +316,40 @@ public:
|
||||
{
|
||||
return ToInteger (Time::FS);
|
||||
}
|
||||
|
||||
/**
|
||||
* \returns an approximation in minutes of the time stored in this
|
||||
* instance.
|
||||
*/
|
||||
inline double GetMinutes (void) const
|
||||
{
|
||||
return ToDouble (Time::MIN);
|
||||
}
|
||||
/**
|
||||
* \returns an approximation in hours of the time stored in this
|
||||
* instance.
|
||||
*/
|
||||
inline double GetHours (void) const
|
||||
{
|
||||
return ToDouble (Time::H);
|
||||
}
|
||||
/**
|
||||
* \returns an approximation in days of the time stored in this
|
||||
* instance.
|
||||
*/
|
||||
inline double GetDays (void) const
|
||||
{
|
||||
return ToDouble (Time::D);
|
||||
}
|
||||
/**
|
||||
* \returns an approximation in years of the time stored in this
|
||||
* instance.
|
||||
*/
|
||||
inline double GetYears (void) const
|
||||
{
|
||||
return ToDouble (Time::Y);
|
||||
}
|
||||
|
||||
/**
|
||||
* \returns the raw time value, in the current units
|
||||
*/
|
||||
@@ -762,7 +804,66 @@ inline Time FemtoSeconds (uint64_t fs)
|
||||
{
|
||||
return Time::FromInteger (fs, Time::FS);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief create ns3::Time instances in units of minutes (equal to 60 seconds).
|
||||
*
|
||||
* For example:
|
||||
* \code
|
||||
* Time t = Minutes (2.0);
|
||||
* Simulator::Schedule (Minutes (5.0), ...);
|
||||
* \endcode
|
||||
* \param minutes mintues value
|
||||
* \relates ns3::Time
|
||||
*/
|
||||
inline Time Minutes (double minutes)
|
||||
{
|
||||
return Time::FromDouble (minutes, Time::MIN);
|
||||
}
|
||||
/**
|
||||
* \brief create ns3::Time instances in units of hours (equal to 60 minutes).
|
||||
*
|
||||
* For example:
|
||||
* \code
|
||||
* Time t = Hours (2.0);
|
||||
* Simulator::Schedule (Hours (5.0), ...);
|
||||
* \endcode
|
||||
* \param hours hours value
|
||||
* \relates ns3::Time
|
||||
*/
|
||||
inline Time Hours (double hours)
|
||||
{
|
||||
return Time::FromDouble (hours, Time::H);
|
||||
}
|
||||
/**
|
||||
* \brief create ns3::Time instances in units of days (equal to 24 hours).
|
||||
*
|
||||
* For example:
|
||||
* \code
|
||||
* Time t = Days (2.0);
|
||||
* Simulator::Schedule (Days (5.0), ...);
|
||||
* \endcode
|
||||
* \param days days value
|
||||
* \relates ns3::Time
|
||||
*/
|
||||
inline Time Days (double days)
|
||||
{
|
||||
return Time::FromDouble (days, Time::D);
|
||||
}
|
||||
/**
|
||||
* \brief create ns3::Time instances in units of years (equal to 365 days).
|
||||
*
|
||||
* For example:
|
||||
* \code
|
||||
* Time t = Years (2.0);
|
||||
* Simulator::Schedule (Years (5.0), ...);
|
||||
* \endcode
|
||||
* \param years years value
|
||||
* \relates ns3::Time
|
||||
*/
|
||||
inline Time Years (double years)
|
||||
{
|
||||
return Time::FromDouble (years, Time::Y);
|
||||
}
|
||||
|
||||
/**
|
||||
* \see Seconds(double)
|
||||
@@ -812,6 +913,38 @@ inline Time FemtoSeconds (int64x64_t fs)
|
||||
{
|
||||
return Time::From (fs, Time::FS);
|
||||
}
|
||||
/**
|
||||
* \see Minutes(uint64_t)
|
||||
* \relates ns3::Time
|
||||
*/
|
||||
inline Time Minutes (int64x64_t minutes)
|
||||
{
|
||||
return Time::From (minutes, Time::MIN);
|
||||
}
|
||||
/**
|
||||
* \see Minutes(uint64_t)
|
||||
* \relates ns3::Time
|
||||
*/
|
||||
inline Time Hours (int64x64_t hours)
|
||||
{
|
||||
return Time::From (hours, Time::H);
|
||||
}
|
||||
/**
|
||||
* \see Minutes(uint64_t)
|
||||
* \relates ns3::Time
|
||||
*/
|
||||
inline Time Days (int64x64_t days)
|
||||
{
|
||||
return Time::From (days, Time::D);
|
||||
}
|
||||
/**
|
||||
* \see Minutes(uint64_t)
|
||||
* \relates ns3::Time
|
||||
*/
|
||||
inline Time Years (int64x64_t years)
|
||||
{
|
||||
return Time::From (years, Time::Y);
|
||||
}
|
||||
|
||||
// internal function not publicly documented
|
||||
inline Time TimeStep (uint64_t ts)
|
||||
|
||||
@@ -123,6 +123,22 @@ Time::Time (const std::string& s)
|
||||
{
|
||||
*this = Time::FromDouble (r, Time::FS);
|
||||
}
|
||||
else if (trailer == std::string ("min"))
|
||||
{
|
||||
*this = Time::FromDouble (r, Time::MIN);
|
||||
}
|
||||
else if (trailer == std::string ("h"))
|
||||
{
|
||||
*this = Time::FromDouble (r, Time::H);
|
||||
}
|
||||
else if (trailer == std::string ("d"))
|
||||
{
|
||||
*this = Time::FromDouble (r, Time::D);
|
||||
}
|
||||
else if (trailer == std::string ("y"))
|
||||
{
|
||||
*this = Time::FromDouble (r, Time::Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ABORT_MSG ("Can't Parse Time " << s);
|
||||
@@ -176,21 +192,41 @@ Time::SetResolution (enum Unit unit, struct Resolution *resolution,
|
||||
ConvertTimes (unit);
|
||||
}
|
||||
|
||||
int8_t power [LAST] = { 15, 12, 9, 6, 3, 0};
|
||||
// Y, D, H, MIN, S, MS, US, NS, PS, FS
|
||||
const int8_t power [LAST] = { 17, 17, 17, 16, 15, 12, 9, 6, 3, 0 };
|
||||
const int32_t coefficient [LAST] = { 315360, 864, 36, 6, 1, 1, 1, 1, 1, 1 };
|
||||
for (int i = 0; i < Time::LAST; i++)
|
||||
{
|
||||
int shift = power[i] - power[(int)unit];
|
||||
int64_t factor = (int64_t) std::pow (10, std::fabs (shift));
|
||||
int quotient = 1;
|
||||
if (coefficient[i] > coefficient[(int) unit])
|
||||
{
|
||||
quotient = coefficient[i] / coefficient[(int) unit];
|
||||
NS_ASSERT (quotient * coefficient[(int) unit] == coefficient[i]);
|
||||
}
|
||||
else if (coefficient[i] < coefficient[(int) unit])
|
||||
{
|
||||
quotient = coefficient[(int) unit] / coefficient[i];
|
||||
NS_ASSERT (quotient * coefficient[i] == coefficient[(int) unit]);
|
||||
}
|
||||
NS_LOG_DEBUG ("SetResolution for unit " << (int) unit << " loop iteration " << i
|
||||
<< " has shift " << shift << " has quotient " << quotient);
|
||||
int64_t factor = static_cast<int64_t> (std::pow (10, std::fabs (shift)) * quotient);
|
||||
double realFactor = std::pow (10, (double) shift)
|
||||
* static_cast<double> (coefficient[i]) / coefficient[(int) unit];
|
||||
NS_LOG_DEBUG ("SetResolution factor " << factor << " real factor " << realFactor);
|
||||
struct Information *info = &resolution->info[i];
|
||||
info->factor = factor;
|
||||
if (shift == 0)
|
||||
// here we could equivalently check for realFactor == 1.0 but it's better
|
||||
// to avoid checking equality of doubles
|
||||
if (shift == 0 && quotient == 1)
|
||||
{
|
||||
info->timeFrom = int64x64_t (1);
|
||||
info->timeTo = int64x64_t (1);
|
||||
info->toMul = true;
|
||||
info->fromMul = true;
|
||||
}
|
||||
else if (shift > 0)
|
||||
else if (realFactor > 1)
|
||||
{
|
||||
info->timeFrom = int64x64_t (factor);
|
||||
info->timeTo = int64x64_t::Invert (factor);
|
||||
@@ -199,7 +235,7 @@ Time::SetResolution (enum Unit unit, struct Resolution *resolution,
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT (shift < 0);
|
||||
NS_ASSERT (realFactor < 1);
|
||||
info->timeFrom = int64x64_t::Invert (factor);
|
||||
info->timeTo = int64x64_t (factor);
|
||||
info->toMul = true;
|
||||
@@ -368,6 +404,18 @@ operator<< (std::ostream& os, const Time & time)
|
||||
case Time::FS:
|
||||
unit = "fs";
|
||||
break;
|
||||
case Time::MIN:
|
||||
unit = "min";
|
||||
break;
|
||||
case Time::H:
|
||||
unit = "h";
|
||||
break;
|
||||
case Time::D:
|
||||
unit = "d";
|
||||
break;
|
||||
case Time::Y:
|
||||
unit = "y";
|
||||
break;
|
||||
case Time::LAST:
|
||||
NS_ABORT_MSG ("can't be reached");
|
||||
unit = "unreachable";
|
||||
|
||||
@@ -47,6 +47,22 @@ TimeSimpleTestCase::DoSetup (void)
|
||||
void
|
||||
TimeSimpleTestCase::DoRun (void)
|
||||
{
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (Years (1.0).GetYears (), 1.0, Years (1).GetYears (),
|
||||
"is 1 really 1 ?");
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (Years (10.0).GetYears (), 10.0, Years (1).GetYears (),
|
||||
"is 10 really 10 ?");
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (Days (1.0).GetDays (), 1.0, Days (1).GetDays (),
|
||||
"is 1 really 1 ?");
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (Days (10.0).GetDays (), 10.0, Days (1).GetDays (),
|
||||
"is 10 really 10 ?");
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (Hours (1.0).GetHours (), 1.0, Hours (1).GetHours (),
|
||||
"is 1 really 1 ?");
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (Hours (10.0).GetHours (), 10.0, Hours (1).GetHours (),
|
||||
"is 10 really 10 ?");
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (Minutes (1.0).GetMinutes (), 1.0, Minutes (1).GetMinutes (),
|
||||
"is 1 really 1 ?");
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (Minutes (10.0).GetMinutes (), 10.0, Minutes (1).GetMinutes (),
|
||||
"is 10 really 10 ?");
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (Seconds (1.0).GetSeconds (), 1.0, TimeStep (1).GetSeconds (),
|
||||
"is 1 really 1 ?");
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (Seconds (10.0).GetSeconds (), 10.0, TimeStep (1).GetSeconds (),
|
||||
|
||||
Reference in New Issue
Block a user