00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "nstime.h"
00023 #include "ns3/fatal-error.h"
00024 #include "ns3/global-value.h"
00025 #include "ns3/enum.h"
00026 #include "ns3/string.h"
00027 #include "ns3/object.h"
00028 #include "ns3/config.h"
00029 #include <math.h>
00030
00031 namespace ns3 {
00032
00033 namespace TimeStepPrecision {
00034
00035 static const uint64_t MS_FACTOR = (uint64_t)pow(10,3);
00036 static const uint64_t US_FACTOR = (uint64_t)pow(10,6);
00037 static const uint64_t NS_FACTOR = (uint64_t)pow(10,9);
00038 static const uint64_t PS_FACTOR = (uint64_t)pow(10,12);
00039 static const uint64_t FS_FACTOR = (uint64_t)pow(10,15);
00040 static uint64_t g_tsPrecFactor = NS_FACTOR;
00041
00042 static GlobalValue g_precisionDefaultValue ("TimeStepPrecision",
00043 "The time unit of the internal 64 bit integer time.",
00044 EnumValue (NS),
00045 MakeEnumChecker (NS, "NS",
00046 S, "S",
00047 MS, "MS",
00048 US, "US",
00049 PS, "PS",
00050 FS, "FS")
00051 );
00052
00053 precision_t
00054 Get (void)
00055 {
00056 EnumValue v;
00057 g_precisionDefaultValue.GetValue (v);
00058 return (precision_t) v.Get ();
00059 }
00060
00061 void
00062 Set (precision_t precision)
00063 {
00064 g_precisionDefaultValue.SetValue (EnumValue (precision));
00065 g_tsPrecFactor = (uint64_t)pow(10, precision);
00066 }
00067
00068 }
00069
00070 TimeUnit<1>::TimeUnit(const std::string& s)
00071 {
00072 std::string::size_type n = s.find_first_not_of("0123456789.");
00073 if (n != std::string::npos)
00074 {
00075 std::istringstream iss;
00076 iss.str (s.substr(0, n));
00077 double r;
00078 iss >> r;
00079 std::string trailer = s.substr(n, std::string::npos);
00080 if (trailer == std::string("s"))
00081 {
00082 m_data = HighPrecision (r * TimeStepPrecision::g_tsPrecFactor);
00083 return;
00084 }
00085 if (trailer == std::string("ms"))
00086 {
00087 m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor/pow(10,3))),
00088 false);
00089 return;
00090 }
00091 if (trailer == std::string("us"))
00092 {
00093 m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor/pow(10,6))),
00094 false);
00095 return;
00096 }
00097 if (trailer == std::string("ns"))
00098 {
00099 m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor/pow(10,9))),
00100 false);
00101 return;
00102 }
00103 if (trailer == std::string("ps"))
00104 {
00105 m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor/pow(10,12))),
00106 false);
00107 return;
00108 }
00109 if (trailer == std::string("fs"))
00110 {
00111 m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor/pow(10,15))),
00112 false);
00113 return;
00114 }
00115 NS_FATAL_ERROR("Can't Parse Time "<<s);
00116 }
00117
00118
00119 std::istringstream iss;
00120 iss. str (s);
00121 double v;
00122 iss >> v;
00123 m_data = HighPrecision (v * TimeStepPrecision::g_tsPrecFactor);
00124 }
00125
00126 double
00127 TimeUnit<1>::GetSeconds (void) const
00128 {
00129 double timeValue = GetHighPrecision ().GetDouble ();
00130 return timeValue/TimeStepPrecision::g_tsPrecFactor;
00131 }
00132
00133 int64_t
00134 TimeUnit<1>::ConvertToUnits (int64_t timeValue, uint64_t unitFactor) const
00135 {
00136 uint64_t precFactor;
00137
00138 if (TimeStepPrecision::g_tsPrecFactor < unitFactor)
00139 {
00140 precFactor = unitFactor / TimeStepPrecision::g_tsPrecFactor;
00141 timeValue = timeValue * precFactor;
00142 }
00143 else
00144 {
00145 precFactor = TimeStepPrecision::g_tsPrecFactor / unitFactor;
00146 timeValue = timeValue / precFactor;
00147 }
00148 return timeValue;
00149 }
00150
00151
00152 int64_t
00153 TimeUnit<1>::GetMilliSeconds (void) const
00154 {
00155 int64_t ts = GetTimeStep();
00156 int64_t ms = ConvertToUnits(ts, TimeStepPrecision::MS_FACTOR);
00157
00158 return ms;
00159 }
00160 int64_t
00161 TimeUnit<1>::GetMicroSeconds (void) const
00162 {
00163 int64_t ts = GetTimeStep();
00164 int64_t us = ConvertToUnits(ts, TimeStepPrecision::US_FACTOR);
00165
00166 return us;
00167 }
00168 int64_t
00169 TimeUnit<1>::GetNanoSeconds (void) const
00170 {
00171 int64_t ts = GetTimeStep();
00172 int64_t ns = ConvertToUnits(ts, TimeStepPrecision::NS_FACTOR);
00173
00174 return ns;
00175 }
00176 int64_t
00177 TimeUnit<1>::GetPicoSeconds (void) const
00178 {
00179 int64_t ts = GetTimeStep();
00180 int64_t ps = ConvertToUnits(ts, TimeStepPrecision::PS_FACTOR);
00181
00182 return ps;
00183 }
00184 int64_t
00185 TimeUnit<1>::GetFemtoSeconds (void) const
00186 {
00187 int64_t ts = GetTimeStep();
00188 int64_t fs = ConvertToUnits(ts, TimeStepPrecision::FS_FACTOR);
00189
00190 return fs;
00191 }
00192
00193
00194
00195
00196 int64_t
00197 TimeUnit<1>::GetTimeStep (void) const
00198 {
00199 int64_t timeValue = GetHighPrecision ().GetInteger ();
00200 return timeValue;
00201 }
00202
00203
00204 std::ostream&
00205 operator<< (std::ostream& os, const Time & time)
00206 {
00207 std::string unit;
00208 switch (TimeStepPrecision::Get ()) {
00209 case TimeStepPrecision::S:
00210 unit = "s";
00211 break;
00212 case TimeStepPrecision::MS:
00213 unit = "ms";
00214 break;
00215 case TimeStepPrecision::US:
00216 unit = "us";
00217 break;
00218 case TimeStepPrecision::NS:
00219 unit = "ns";
00220 break;
00221 case TimeStepPrecision::PS:
00222 unit = "ps";
00223 break;
00224 case TimeStepPrecision::FS:
00225 unit = "fs";
00226 break;
00227 }
00228 os << time.GetTimeStep () << unit;
00229 return os;
00230 }
00231 std::istream& operator>> (std::istream& is, Time & time)
00232 {
00233 std::string value;
00234 is >> value;
00235 std::string::size_type n = value.find_first_not_of("0123456789.");
00236 if (n == std::string::npos)
00237 {
00238 is.setstate (std::ios_base::failbit);
00239 return is;
00240 }
00241 std::string trailer = value.substr(n, value.size ()-n);
00242 std::istringstream iss;
00243 iss.str (value.substr(0, n));
00244
00245 if (trailer == std::string("s"))
00246 {
00247 double v;
00248 iss >> v;
00249 time = Seconds (v);
00250 return is;
00251 }
00252 uint64_t integer;
00253 iss >> integer;
00254 if (is.bad () || is.fail ())
00255 {
00256 is.setstate (std::ios_base::failbit);
00257 }
00258 else if (trailer == std::string("ms"))
00259 {
00260 time = MilliSeconds (integer);
00261 }
00262 else if (trailer == std::string("us"))
00263 {
00264 time = MicroSeconds (integer);
00265 }
00266 else if (trailer == std::string("ns"))
00267 {
00268 time = NanoSeconds (integer);
00269 }
00270 else if (trailer == std::string("ps"))
00271 {
00272 time = PicoSeconds (integer);
00273 }
00274 else if (trailer == std::string("fs"))
00275 {
00276 time = FemtoSeconds (integer);
00277 }
00278 else
00279 {
00280 is.setstate (std::ios_base::failbit);
00281 }
00282 return is;
00283 }
00284
00285 Time Seconds (double seconds)
00286 {
00287 double d_sec = seconds * TimeStepPrecision::g_tsPrecFactor;
00288 return Time (HighPrecision (d_sec));
00289
00290 }
00291
00292 uint64_t
00293 TimeUnit<1>::UnitsToTimestep (uint64_t unitValue,
00294 uint64_t unitFactor)
00295 {
00296 uint64_t precFactor;
00297
00298 if (TimeStepPrecision::g_tsPrecFactor < unitFactor)
00299 {
00300 precFactor = unitFactor / TimeStepPrecision::g_tsPrecFactor;
00301 unitValue = unitValue / precFactor;
00302 }
00303 else
00304 {
00305 precFactor = TimeStepPrecision::g_tsPrecFactor / unitFactor;
00306 unitValue = unitValue * precFactor;
00307 }
00308 return unitValue;
00309 }
00310
00311 ATTRIBUTE_VALUE_IMPLEMENT (Time);
00312 ATTRIBUTE_CHECKER_IMPLEMENT (Time);
00313
00314 Time MilliSeconds (uint64_t ms)
00315 {
00316 uint64_t ts = TimeUnit<1>::UnitsToTimestep(ms, TimeStepPrecision::MS_FACTOR);
00317 return TimeStep(ts);
00318 }
00319
00320 Time MicroSeconds (uint64_t us)
00321 {
00322 uint64_t ts = TimeUnit<1>::UnitsToTimestep(us, TimeStepPrecision::US_FACTOR);
00323 return TimeStep(ts);
00324 }
00325
00326 Time NanoSeconds (uint64_t ns)
00327 {
00328 uint64_t ts = TimeUnit<1>::UnitsToTimestep(ns, TimeStepPrecision::NS_FACTOR);
00329 return TimeStep(ts);
00330 }
00331 Time PicoSeconds (uint64_t ps)
00332 {
00333 uint64_t ts = TimeUnit<1>::UnitsToTimestep(ps, TimeStepPrecision::PS_FACTOR);
00334 return TimeStep(ts);
00335 }
00336 Time FemtoSeconds (uint64_t fs)
00337 {
00338 uint64_t ts = TimeUnit<1>::UnitsToTimestep(fs, TimeStepPrecision::FS_FACTOR);
00339 return TimeStep(ts);
00340 }
00341
00342
00343
00344
00345
00346
00347 Time TimeStep (uint64_t ts)
00348 {
00349 return Time (HighPrecision (ts, false));
00350 }
00351
00352 TimeUnit<0>::TimeUnit (double scalar)
00353 : m_data (HighPrecision (scalar))
00354 {}
00355
00356 double
00357 TimeUnit<0>::GetDouble (void) const
00358 {
00359 return GetHighPrecision ().GetDouble ();
00360 }
00361
00362 }
00363
00364
00365 #ifdef RUN_SELF_TESTS
00366
00367 #include "ns3/test.h"
00368
00369
00370 namespace ns3 {
00371
00372 class TimeTests : public Test
00373 {
00374 public:
00375 TimeTests ();
00376 virtual ~TimeTests ();
00377 virtual bool RunTests (void);
00378
00379
00380
00381
00382
00383 void CheckTimeSec(std::string test_id, double actual, double expected,
00384 bool *flag, double precMultFactor = 1,
00385 bool verbose = false);
00386
00387
00388
00389
00390 void CheckTime(std::string test_id, int64_t actual, int64_t expected,
00391 bool *flag, double precMultFactor = 1,
00392 bool verbose = false);
00393
00394
00395
00396
00397 void CheckOperations(Time t0, Time t1, bool *ok, bool verbose = false);
00398
00399
00400
00401
00402
00403
00404 void CheckPrecision(TimeStepPrecision::precision_t prec, uint64_t val, bool *ok,
00405 bool verbose = false);
00406
00407
00408
00409
00410
00411
00412 void CheckConversions(uint64_t tval, bool *ok, bool verbose = false);
00413
00414
00415
00416
00417 void CheckOld(bool *ok);
00418 };
00419
00420 TimeTests::TimeTests ()
00421 : Test ("Time")
00422 {}
00423 TimeTests::~TimeTests ()
00424 {}
00425
00426 bool TimeTests::RunTests (void)
00427 {
00428 bool result = true;
00429
00430 Time t0, t1;
00431
00432 CheckOld(&result);
00433
00434 t0 = MilliSeconds ((uint64_t)10.0);
00435 t1 = MilliSeconds ((uint64_t)11.0);
00436
00437 CheckOperations(t0, t1, &result);
00438
00439
00440
00441
00442
00443
00444 CheckConversions((uint64_t)5, &result);
00445 CheckConversions((uint64_t)0, &result);
00446 CheckConversions((uint64_t)783, &result);
00447 CheckConversions((uint64_t)1132, &result);
00448
00449
00450
00451 if (TimeStepPrecision::Get () != TimeStepPrecision::NS) {
00452 result = false;
00453 }
00454
00455 CheckPrecision(TimeStepPrecision::US, 7, &result);
00456
00457 CheckConversions((uint64_t)7, &result);
00458 CheckConversions((uint64_t)546, &result);
00459 CheckConversions((uint64_t)6231, &result);
00460
00461
00462 CheckPrecision(TimeStepPrecision::MS, 3, &result);
00463
00464 CheckConversions((uint64_t)3, &result);
00465 CheckConversions((uint64_t)134, &result);
00466 CheckConversions((uint64_t)2341, &result);
00467
00468
00469 CheckPrecision(TimeStepPrecision::PS, 21, &result);
00470
00471 CheckConversions((uint64_t)4, &result);
00472 CheckConversions((uint64_t)342, &result);
00473 CheckConversions((uint64_t)1327, &result);
00474
00475
00476 CheckPrecision(TimeStepPrecision::NS, 12, &result);
00477 CheckConversions((uint64_t)12, &result);
00478
00479 CheckPrecision(TimeStepPrecision::S, 7, &result);
00480 CheckConversions((uint64_t)7, &result);
00481
00482 CheckPrecision(TimeStepPrecision::FS, 5, &result);
00483 CheckConversions((uint64_t)5, &result);
00484
00485 TimeStepPrecision::Set (TimeStepPrecision::NS);
00486
00487 Config::SetGlobal ("TimeStepPrecision", StringValue ("S"));
00488 Config::SetGlobal ("TimeStepPrecision", StringValue ("MS"));
00489 Config::SetGlobal ("TimeStepPrecision", StringValue ("US"));
00490 Config::SetGlobal ("TimeStepPrecision", StringValue ("NS"));
00491 Config::SetGlobal ("TimeStepPrecision", StringValue ("PS"));
00492 Config::SetGlobal ("TimeStepPrecision", StringValue ("FS"));
00493
00494
00495 Time tooBig = TimeStep (0x8000000000000000LL);
00496 NS_TEST_ASSERT (tooBig.IsNegative ());
00497 tooBig = TimeStep (0xffffffffffffffffLL);
00498 NS_TEST_ASSERT (tooBig.IsNegative ());
00499 tooBig = TimeStep (0x7fffffffffffffffLL);
00500 NS_TEST_ASSERT (tooBig.IsPositive ());
00501 tooBig += TimeStep (1);
00502 NS_TEST_ASSERT (tooBig.IsNegative ());
00503
00504 return result;
00505 }
00506
00507 void TimeTests::CheckOld (bool *ok)
00508 {
00509 double dt0, dt1, dt2;
00510 int64_t it0, it1;
00511
00512 Time t0 = Seconds (10.0);
00513 CheckTimeSec("old 1", t0.GetSeconds(), 10.0, ok);
00514
00515 Time t1 = Seconds (11.0);
00516 CheckTimeSec("old 2", t1.GetSeconds(), 11.0, ok);
00517
00518 t0 = Seconds (1.5);
00519 CheckTimeSec("old 3", t0.GetSeconds(), 1.5, ok);
00520
00521 t0 = Seconds (-1.5);
00522 CheckTimeSec("old 4", t0.GetSeconds(), -1.5, ok);
00523
00524 t0 = MilliSeconds ((uint64_t)10.0);
00525 dt0 = t0.GetSeconds();
00526 CheckTimeSec("old 5", dt0, 0.01, ok);
00527
00528 t1 = MilliSeconds ((uint64_t)11.0);
00529 dt1 = t1.GetSeconds();
00530 CheckTimeSec("old 6", dt1, 0.011, ok);
00531
00532 Time t2, t3;
00533
00534 t2 = t1 - t0;
00535 if (!t2.IsStrictlyPositive ())
00536 {
00537 ok = false;
00538 }
00539 dt2 = t2.GetSeconds();
00540 CheckTimeSec("old 7", dt2, dt1-dt0, ok);
00541
00542 t2 = t1 - t1;
00543 if (!t2.IsZero ())
00544 {
00545 ok = false;
00546 }
00547 dt2 = t2.GetSeconds();
00548 CheckTimeSec("old 8", dt2, dt1-dt1, ok);
00549
00550 t2 = t0 - t1;
00551 if (!t2.IsStrictlyNegative ())
00552 {
00553 ok = false;
00554 }
00555 dt2 = t2.GetSeconds();
00556 CheckTimeSec("old 9", dt2, dt0-dt1, ok);
00557
00558 t1 = NanoSeconds(15);
00559 it0 = t0.GetNanoSeconds();
00560 it1 = t1.GetNanoSeconds();
00561 TimeUnit<-2> tu4 = t0 / (t1 * t1 * t1);
00562 CheckTime("old 10", tu4.GetHighPrecision().GetInteger(), it0 / (it1*it1*it1),
00563 ok, 1e9);
00564
00565 Time tmp = MilliSeconds (0);
00566 if ((tmp != NanoSeconds (0)) ||
00567 (tmp > NanoSeconds (0)) ||
00568 (tmp < NanoSeconds (0)))
00569 {
00570 ok = false;
00571 }
00572
00573 Time t4;
00574 t4 = Seconds (10.0) * Scalar (1.5);
00575 CheckTimeSec("old 11", t4.GetSeconds(), 10, ok);
00576
00577 Time t5;
00578 t5 = NanoSeconds (10) * Scalar (1.5);
00579 CheckTime("old 12", t5.GetNanoSeconds(), 10, ok);
00580
00581 t4 = Seconds (10.0) * Scalar (15) / Scalar (10);
00582 CheckTimeSec("old 13", t4.GetSeconds(), 15, ok);
00583
00584 t5 = NanoSeconds (10) * Scalar (15) / Scalar (10);
00585 CheckTime("old 14", t5.GetNanoSeconds(), 15, ok);
00586
00587
00588 double foo = (t1 + t2).GetSeconds ();
00589 dt1 = t1.GetSeconds();
00590 dt2 = t2.GetSeconds();
00591 CheckTimeSec("old 15", foo, dt1+dt2, ok);
00592
00593 foo += (t4 == t5)? 1 : 0;
00594 CheckTimeSec("old 16", foo, dt1+dt2, ok);
00595
00596 foo = (t1/t2).GetDouble ();
00597 CheckTimeSec("old 17", foo, dt1/dt2, ok);
00598 }
00599
00600
00601 void TimeTests::CheckOperations(Time t0, Time t1, bool *ok, bool verbose)
00602 {
00603
00604 if (verbose)
00605 std::cout << std::endl << "Check operations: "
00606 << t0 << " " << t1 << std::endl;
00607
00608 Time t2, t3;
00609 double it0, it1, it2, it3, itu2, itu3;
00610 int64_t iti0;
00611
00612 it0 = t0.GetSeconds();
00613 it1 = t1.GetSeconds();
00614
00615 t2 = t0 - t1;
00616 it2 = t2.GetSeconds();
00617 CheckTimeSec("ops 1", it2, it0-it1, ok);
00618
00619 t3 = t2 * t0 / t0;
00620 it3 = t3.GetSeconds();
00621 CheckTimeSec("ops 2a", it3, it2*it0/it0, ok);
00622
00623 t3 = t2 * t0 / t1;
00624 it3 = t3.GetSeconds();
00625 CheckTimeSec("ops 2", it3, it2*it0/it1, ok);
00626
00627 t3 = t0 * t2 / t1;
00628 it3 = t3.GetSeconds();
00629 CheckTimeSec("ops 3", it3, it0*it2/it1, ok);
00630
00631 t3 = t0 * t1 / t2;
00632 it3 = t3.GetSeconds();
00633 CheckTimeSec("ops 4", it3, it0*it1/it2, ok);
00634
00635 t3 = t0 * (t1 / t2);
00636 it3 = t3.GetSeconds();
00637 CheckTimeSec("ops 5", it3, it0*(it1/it2), ok);
00638
00639 t3 = (t0 * t1) / t2;
00640 it3 = t3.GetSeconds();
00641 CheckTimeSec("ops 6", it3, (it0*it1)/it2, ok);
00642
00643 t3 = t0 / t1 * t2;
00644 it3 = t3.GetSeconds();
00645 CheckTimeSec("ops 7", it3, it0/it1*it2, ok);
00646
00647 t3 = (t0 / t1) * t2;
00648 it3 = t3.GetSeconds();
00649 CheckTimeSec("ops 8", it3, (it0/it1)*it2, ok);
00650
00651 t3 = t0 * Scalar (10.0);
00652 it3 = t3.GetSeconds();
00653 CheckTimeSec("ops 9", it3, it0*10, ok);
00654
00655 t3 = Scalar (10.0) * t0;
00656 it3 = t3.GetSeconds();
00657 CheckTimeSec("ops 10", it3, 10 * it0, ok);
00658
00659 t3 = Scalar (10.0) * t0 / t2 * t1;
00660 it3 = t3.GetSeconds();
00661 CheckTimeSec("ops 11", it3, 10 * it0 / it2 * it1, ok);
00662
00663 t3 = (Scalar (10.0) * t0 ) / t2 * t1;
00664 it3 = t3.GetSeconds();
00665 CheckTimeSec("ops 12", it3, (10 * it0) / it2 * it1, ok);
00666
00667 TimeInvert ti0;
00668 ti0 = t0 / (t1 * t2);
00669 iti0 = ti0.GetHighPrecision().GetInteger();
00670
00671
00672
00673 Scalar s0 = t0 / t1;
00674 CheckTimeSec("ops 14", s0.GetDouble(), it0/it1, ok);
00675
00676 Scalar s1;
00677 s1 = t0 * t1 / (t2 * t0);
00678 CheckTimeSec("ops 15", s1.GetDouble(), it0*it1/(it2*it0), ok);
00679
00680 TimeUnit<0> tu0;
00681 tu0 = s0;
00682 CheckTimeSec("ops 16", tu0.GetDouble(), s0.GetDouble(), ok);
00683
00684 TimeUnit<1> tu1;
00685 tu1 = t0;
00686 CheckTimeSec("ops 17", tu1.GetSeconds(), it0, ok);
00687
00688 TimeUnit<2> tu2;
00689 tu2 = t0 * t1;
00690 CheckTimeSec("ops 18", tu2.GetHighPrecision().GetInteger()/(1e18),
00691 it0 * it1, ok);
00692 itu2 = tu2.GetHighPrecision().GetInteger()/(1e18);
00693
00694 TimeUnit<3> tu3;
00695 tu3 = t0 / Scalar(10e6) * tu2;
00696 CheckTimeSec("ops 19", tu3.GetHighPrecision().GetInteger()/(1e27),
00697 it0 / 1000000 * itu2, ok);
00698 itu3 = tu3.GetHighPrecision().GetInteger()/(1e27);
00699 }
00700
00701 void TimeTests::CheckConversions(uint64_t tval, bool *ok, bool verbose)
00702 {
00703 Time t_sec, t_ms, t_us, t_ns, t_ps, t_fs;
00704
00705 if (verbose)
00706 {
00707 std::cout << std::endl << "Check conversions: " << tval << std::endl;
00708 }
00709
00710
00711 t_sec = Seconds((double)tval);
00712 CheckTimeSec("conv sec sec", t_sec.GetSeconds(), (double)tval, ok);
00713 CheckTime("conv sec ms", t_sec.GetMilliSeconds(), (int64_t)(tval*1e3), ok, 1e3);
00714 CheckTime("conv sec us", t_sec.GetMicroSeconds(), (int64_t)(tval*1e6), ok, 1e6);
00715 CheckTime("conv sec ns", t_sec.GetNanoSeconds(), (int64_t)(tval*1e9), ok, 1e9);
00716 CheckTime("conv sec ps", t_sec.GetPicoSeconds(),
00717 (int64_t)(tval*1e12), ok, 1e12);
00718 CheckTime("conv sec fs", t_sec.GetFemtoSeconds(),
00719 (int64_t)(tval*1e15), ok, 1e15);
00720
00721
00722 t_ms = MilliSeconds(tval);
00723 CheckTimeSec("conv ms sec", t_ms.GetSeconds(), (double)tval/1e3, ok);
00724 CheckTime("conv ms ms", t_ms.GetMilliSeconds(), (int64_t)(tval), ok, 1e3);
00725 CheckTime("conv ms us", t_ms.GetMicroSeconds(), (int64_t)(tval*1e3), ok, 1e6);
00726 CheckTime("conv ms ns", t_ms.GetNanoSeconds(), (int64_t)(tval*1e6), ok, 1e9);
00727 CheckTime("conv ms ps", t_ms.GetPicoSeconds(), (int64_t)(tval*1e9), ok, 1e12);
00728 CheckTime("conv ms fs", t_ms.GetFemtoSeconds(), (int64_t)(tval*1e12), ok, 1e15);
00729
00730
00731 t_us = MicroSeconds(tval);
00732 CheckTimeSec("conv us sec", t_us.GetSeconds(), (double)tval/1e6, ok);
00733 CheckTime("conv us ms", t_us.GetMilliSeconds(), (int64_t)(tval/1e3), ok, 1e3);
00734 CheckTime("conv us us", t_us.GetMicroSeconds(), (int64_t)(tval), ok, 1e6);
00735 CheckTime("conv us ns", t_us.GetNanoSeconds(), (int64_t)(tval*1e3), ok, 1e9);
00736 CheckTime("conv us ps", t_us.GetPicoSeconds(), (int64_t)(tval*1e6), ok, 1e12);
00737 CheckTime("conv us fs", t_us.GetFemtoSeconds(), (int64_t)(tval*1e9), ok, 1e15);
00738
00739
00740 t_ns = NanoSeconds(tval);
00741 CheckTimeSec("conv ns sec", t_ns.GetSeconds(), (double)tval/1e9, ok);
00742 CheckTime("conv ns ms", t_ns.GetMilliSeconds(), (int64_t)(tval/1e6), ok, 1e3);
00743 CheckTime("conv ns us", t_ns.GetMicroSeconds(), (int64_t)(tval/1e3), ok, 1e6);
00744 CheckTime("conv ns ns", t_ns.GetNanoSeconds(), (int64_t)(tval), ok, 1e9);
00745 CheckTime("conv ns ps", t_ns.GetPicoSeconds(), (int64_t)(tval*1e3), ok, 1e12);
00746 CheckTime("conv ns fs", t_ns.GetFemtoSeconds(), (int64_t)(tval*1e6), ok, 1e15);
00747
00748
00749 t_ps = PicoSeconds(tval);
00750 CheckTimeSec("conv ps sec", t_ps.GetSeconds(), (double)tval/1e12, ok);
00751 CheckTime("conv ps ms", t_ps.GetMilliSeconds(), (int64_t)(tval/1e9), ok, 1e3);
00752 CheckTime("conv ps us", t_ps.GetMicroSeconds(), (int64_t)(tval/1e6), ok, 1e6);
00753 CheckTime("conv ps ns", t_ps.GetNanoSeconds(), (int64_t)(tval/1e3), ok, 1e9);
00754 CheckTime("conv ps ps", t_ps.GetPicoSeconds(), (int64_t)(tval), ok, 1e12);
00755 CheckTime("conv ps fs", t_ps.GetFemtoSeconds(), (int64_t)(tval*1e3), ok, 1e15);
00756
00757
00758 t_fs = FemtoSeconds(tval);
00759 CheckTimeSec("conv fs sec", t_fs.GetSeconds(), (double)tval/1e15, ok);
00760 CheckTime("conv fs ms", t_fs.GetMilliSeconds(), (int64_t)(tval/1e12), ok, 1e3);
00761 CheckTime("conv fs us", t_fs.GetMicroSeconds(), (int64_t)(tval/1e9), ok, 1e6);
00762 CheckTime("conv fs ns", t_fs.GetNanoSeconds(), (int64_t)(tval/1e6), ok, 1e9);
00763 CheckTime("conv fs ps", t_fs.GetPicoSeconds(), (int64_t)(tval/1e3), ok, 1e12);
00764 CheckTime("conv fs fs", t_fs.GetFemtoSeconds(), (int64_t)(tval), ok, 1e15);
00765
00766
00767 }
00768
00769 void TimeTests::CheckPrecision(TimeStepPrecision::precision_t prec, uint64_t val, bool *ok,
00770 bool verbose)
00771 {
00772 if (verbose)
00773 {
00774 std::cout << "check precision 10^-" << prec << std::endl;
00775 }
00776
00777 TimeStepPrecision::Set (prec);
00778 if (TimeStepPrecision::Get () != prec)
00779 {
00780 ok = false;
00781 }
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804 }
00805
00806 void TimeTests::CheckTimeSec (std::string test_id, double actual,
00807 double expected, bool *flag, double precMultFactor,
00808 bool verbose)
00809 {
00810 double prec = pow(10,-((double)(ns3::TimeStepPrecision::Get ()))) * precMultFactor;
00811 if ((actual < (expected-prec)) || (actual > (expected+prec)))
00812 {
00813 std::cout << "FAIL " << test_id
00814 << " Expected:" << expected
00815 << " Actual: " << actual
00816 << " Precision: " << prec << std::endl;
00817 *flag = false;
00818 }
00819 else
00820 {
00821 if (verbose)
00822 {
00823 std::cout << "PASS " << test_id
00824 << " Expected:" << expected
00825 << " Actual: " << actual
00826 << " Precision: " << prec << std::endl;
00827 }
00828 }
00829 }
00830
00831 void TimeTests::CheckTime (std::string test_id, int64_t actual,
00832 int64_t expected, bool *flag, double precMultFactor,
00833 bool verbose)
00834 {
00835 double prec = pow(10,-((double)(ns3::TimeStepPrecision::Get ()))) * precMultFactor;
00836 if ((actual < (expected-prec)) || (actual > (expected+prec)))
00837 {
00838 std::cout << "FAIL " << test_id
00839 << " Expected:" << expected
00840 << " Actual: " << actual
00841 << " Precision: " << prec << std::endl;
00842 *flag = false;
00843 }
00844 else
00845 {
00846 if (verbose)
00847 {
00848 std::cout << "PASS " << test_id
00849 << " Expected:" << expected
00850 << " Actual: " << actual
00851 << " Precision: " << prec << std::endl;
00852 }
00853 }
00854 }
00855
00856
00857 static TimeTests g_time_tests;
00858
00859 }
00860
00861 #endif