diff --git a/BUILD b/BUILD index 9a2eadc22..df78793ae 100644 --- a/BUILD +++ b/BUILD @@ -29,6 +29,11 @@ Example: scons cflags="-O3 -ffast-math" Example: scons cxxflags="-O3 -ffast-math" - ldflags: flags for the linker: Example: scons ldflags="-L/foo -L/bar" +- high-precision-as-double: set to 'y' to make sure that the + high-precision arithmetics performed by the Time class on + behalf of the user will use doubles. By default, the code + uses 128 integers. +Example: scons high-precision-as-double=y 2) Targets ---------- @@ -166,3 +171,4 @@ my_module.add_external_dep ('pthread') # by default, a module is conceptually a library. If you # want to generate an executable from a module you need to: my_module.set_executable () + diff --git a/SConstruct b/SConstruct index 0b520910a..199f845be 100644 --- a/SConstruct +++ b/SConstruct @@ -48,8 +48,8 @@ simu = build.Ns3Module('simulator', 'src/simulator') ns3.add(simu) simu.add_dep('core') simu.add_sources([ - 'cairo-wideint.c', 'high-precision.cc', + 'cairo-wideint.c', 'time.cc', 'event-id.cc', 'scheduler.cc', @@ -75,8 +75,21 @@ simu.add_inst_headers([ 'scheduler.h', 'scheduler-factory.h', ]) +high_precision_as_double = ARGUMENTS.get('high-precision-as-double', 'n') +if high_precision_as_double == 1: + simu.add_inst_header ('high-precision-double.h') + simu.add_source ('high-precision-double.cc') +else: + simu.add_inst_header ('high-precision-128.h') + simu.add_source ('high-precision-128.cc') + def config_simulator (env, config): retval = [] + high_precision_as_double = ARGUMENTS.get('high-precision-as-double', 'n') + if high_precision_as_double == 'y': + retval.append ('#define USE_HIGH_PRECISION_DOUBLE 1') + else: + retval.append ('#undef USE_HIGH_PRECISION_DOUBLE') if config.CheckCHeader ('stdint.h') == 1: retval.append ('#define HAVE_STDINT_H 1') elif config.CheckCHeader ('inttypes.h') == 1: diff --git a/src/simulator/high-precision-128.cc b/src/simulator/high-precision-128.cc new file mode 100644 index 000000000..f50ade548 --- /dev/null +++ b/src/simulator/high-precision-128.cc @@ -0,0 +1,88 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2006 INRIA + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Mathieu Lacage + */ +#include "high-precision-128.h" + +namespace ns3 { + +HighPrecision::HighPrecision () + : m_high (0), + m_low (0) +{} + +HighPrecision::HighPrecision (int64_t high, int64_t low) + : m_high (high), + m_low (low) +{} + +HighPrecision::HighPrecision (double value) + : m_high (0), // XXX + m_low (0) // XXX +{} + +int64_t +HighPrecision::GetHigh (void) const +{ + return m_high; +} +int64_t +HighPrecision::GetLow (void) const +{ + return m_low; +} + +double +HighPrecision::GetDouble (void) const +{ + return 0.0; +} +bool +HighPrecision::Add (HighPrecision const &o) +{ + return false; +} +bool +HighPrecision::Sub (HighPrecision const &o) +{ + return false; +} +bool +HighPrecision::Mul (HighPrecision const &o) +{ + return false; +} +bool +HighPrecision::Div (HighPrecision const &o) +{ + return false; +} +int +HighPrecision::Compare (HighPrecision const &o) const +{ + return 0; +} +HighPrecision +HighPrecision::Zero (void) +{ + return HighPrecision (0,0); +} + + +}; // namespace ns3 diff --git a/src/simulator/high-precision-128.h b/src/simulator/high-precision-128.h new file mode 100644 index 000000000..5cf75a081 --- /dev/null +++ b/src/simulator/high-precision-128.h @@ -0,0 +1,57 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2006 INRIA + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Mathieu Lacage + */ +#ifndef HIGH_PRECISION_128_H +#define HIGH_PRECISION_128_H + +#include + +namespace ns3 { + +/** + * This should be a high-precision 128bit integer version of + * HighPrecision class. It should also be able to report + * overflow and underflow. + */ +class HighPrecision +{ +public: + HighPrecision (); + HighPrecision (int64_t high, int64_t low); + HighPrecision (double value); + + int64_t GetHigh (void) const; + int64_t GetLow (void) const; + double GetDouble (void) const; + bool Add (HighPrecision const &o); + bool Sub (HighPrecision const &o); + bool Mul (HighPrecision const &o); + bool Div (HighPrecision const &o); + + int Compare (HighPrecision const &o) const; + static HighPrecision Zero (void); +private: + int64_t m_high; + int64_t m_low; +}; + +}; // namespace ns3 + +#endif /* HIGH_PRECISION_128_H */ diff --git a/src/simulator/high-precision-double.cc b/src/simulator/high-precision-double.cc new file mode 100644 index 000000000..44b8ae202 --- /dev/null +++ b/src/simulator/high-precision-double.cc @@ -0,0 +1,94 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2006 INRIA + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Mathieu Lacage + */ +#include "high-precision-double.h" + +#include +#include + + +namespace ns3 { + +const double HighPrecision::MAX_64 = 18446744073709551615.0; + +HighPrecision::HighPrecision () + : m_value (0.0) +{} + +HighPrecision::HighPrecision (int64_t high, int64_t low) + : m_value (((double)high) + (((double)low)/MAX_64)) +{} + +HighPrecision::HighPrecision (double value) + : m_value (value) +{} + +int64_t +HighPrecision::GetHigh (void) const +{ + return (int64_t)floor (m_value); +} +int64_t +HighPrecision::GetLow (void) const +{ + return (int64_t)((m_value - floor (m_value)) * MAX_64); +} + +double +HighPrecision::GetDouble (void) const +{ + return m_value; +} +bool +HighPrecision::Add (HighPrecision const &o) +{ + m_value += o.m_value; + return false; +} +bool +HighPrecision::Sub (HighPrecision const &o) +{ + m_value -= o.m_value; + return false; +} +bool +HighPrecision::Mul (HighPrecision const &o) +{ + m_value *= o.m_value; + return false; +} +bool +HighPrecision::Div (HighPrecision const &o) +{ + m_value /= o.m_value; + return false; +} +int +HighPrecision::Compare (HighPrecision const &o) const +{ + return 0; +} +HighPrecision +HighPrecision::Zero (void) +{ + return HighPrecision (0,0); +} + +}; // namespace ns3 diff --git a/src/simulator/high-precision-double.h b/src/simulator/high-precision-double.h new file mode 100644 index 000000000..5e96b2fb3 --- /dev/null +++ b/src/simulator/high-precision-double.h @@ -0,0 +1,59 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2006 INRIA + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Mathieu Lacage + */ +#ifndef HIGH_PRECISION_DOUBLE_H +#define HIGH_PRECISION_DOUBLE_H + +#include + +namespace ns3 { + +/** + * Obviously, this implementation of the HighPrecision class does + * not provide the 128 bits accuracy since it uses a an IEEE754 double + * to store the value. It also does not report overflows. + * So, it is a nice shortcut but in no way a complete solution. + */ + +class HighPrecision +{ +public: + HighPrecision (); + HighPrecision (int64_t high, int64_t low); + HighPrecision (double value); + + int64_t GetHigh (void) const; + int64_t GetLow (void) const; + double GetDouble (void) const; + bool Add (HighPrecision const &o); + bool Sub (HighPrecision const &o); + bool Mul (HighPrecision const &o); + bool Div (HighPrecision const &o); + + int Compare (HighPrecision const &o) const; + static HighPrecision Zero (void); +private: + static const double MAX_64; + double m_value; +}; + +}; // namespace ns3 + +#endif /* HIGH_PRECISION_DOUBLE_H */ diff --git a/src/simulator/high-precision.cc b/src/simulator/high-precision.cc index f2a5cba81..f8ab9c83e 100644 --- a/src/simulator/high-precision.cc +++ b/src/simulator/high-precision.cc @@ -26,139 +26,6 @@ namespace ns3 { -#ifdef HIGH_PRECISION_I128 - -HighPrecision::HighPrecision () - : m_high (0), - m_low (0) -{} - -HighPrecision::HighPrecision (int64_t high, int64_t low) - : m_high (high), - m_low (low) -{} - -HighPrecision::HighPrecision (double value) - : m_high (0), // XXX - m_low (0) // XXX -{} - -int64_t -HighPrecision::GetHigh (void) const -{ - return m_high; -} -uint32_t -HighPrecision::GetLow (void) const -{ - return m_low; -} - -double -HighPrecision::GetDouble (void) const -{ - return 0.0; -} -bool -HighPrecision::Add (HighPrecision const &o) -{ - return false; -} -bool -HighPrecision::Sub (HighPrecision const &o) -{ - return false; -} -bool -HighPrecision::Mul (HighPrecision const &o) -{ - return false; -} -bool -HighPrecision::Div (HighPrecision const &o) -{ - return false; -} -int -HighPrecision::Compare (HighPrecision const &o) const -{ - return 0; -} -HighPrecision -HighPrecision::Zero (void) -{ - return HighPrecision (0,0); -} - -#else /* HIGH_PRECISION_I128 */ - -const double HighPrecision::MAX_64 = 18446744073709551615.0; - -HighPrecision::HighPrecision () - : m_value (0.0) -{} - -HighPrecision::HighPrecision (int64_t high, int64_t low) - : m_value (((double)high) + (((double)low)/MAX_64)) -{} - -HighPrecision::HighPrecision (double value) - : m_value (value) -{} - -int64_t -HighPrecision::GetHigh (void) const -{ - return (int64_t)floor (m_value); -} -int64_t -HighPrecision::GetLow (void) const -{ - return (int64_t)((m_value - floor (m_value)) * MAX_64); -} - -double -HighPrecision::GetDouble (void) const -{ - return m_value; -} -bool -HighPrecision::Add (HighPrecision const &o) -{ - m_value += o.m_value; - return false; -} -bool -HighPrecision::Sub (HighPrecision const &o) -{ - m_value -= o.m_value; - return false; -} -bool -HighPrecision::Mul (HighPrecision const &o) -{ - m_value *= o.m_value; - return false; -} -bool -HighPrecision::Div (HighPrecision const &o) -{ - m_value /= o.m_value; - return false; -} -int -HighPrecision::Compare (HighPrecision const &o) const -{ - return 0; -} -HighPrecision -HighPrecision::Zero (void) -{ - return HighPrecision (0,0); -} - -#endif /* HIGH_PRECISION_I128 */ - HighPrecision Abs (HighPrecision const &value) { if (value.Compare (HighPrecision::Zero ()) <= 0) diff --git a/src/simulator/high-precision.h b/src/simulator/high-precision.h index 54d9a2938..8f5426c62 100644 --- a/src/simulator/high-precision.h +++ b/src/simulator/high-precision.h @@ -22,71 +22,16 @@ #define HIGH_PRECISION_H #include +#include "ns3/simulator-config.h" + +#ifdef USE_HIGH_PRECISION_DOUBLE +#include "high-precision-double.h" +#else /* USE_HIGH_PRECISION_DOUBLE */ +#include "high-precision-128.h" +#endif /* USE_HIGH_PRECISION_DOUBLE */ namespace ns3 { -#ifdef HIGH_PRECISION_I128 - -/** - * This should be a high-precision 128bit integer version of - * HighPrecision class. It should also be able to report - * overflow and underflow. - */ -class HighPrecision -{ -public: - HighPrecision (); - HighPrecision (int64_t high, int64_t low); - HighPrecision (double value); - - int64_t GetHigh (void) const; - int64_t GetLow (void) const; - double GetDouble (void) const; - bool Add (HighPrecision const &o); - bool Sub (HighPrecision const &o); - bool Mul (HighPrecision const &o); - bool Div (HighPrecision const &o); - - int Compare (HighPrecision const &o) const; - static HighPrecision Zero (void); -private: - int64_t m_high; - int64_t m_low; -}; - -#else /* HIGH_PRECISION_I128 */ - -/** - * Obviously, this implementation of the HighPrecision class does - * not provide the 128 bits accuracy since it uses a an IEEE754 double - * to store the value. It also does not report overflows. - * So, it is a nice shortcut but in no way a complete solution. - */ - -class HighPrecision -{ -public: - HighPrecision (); - HighPrecision (int64_t high, int64_t low); - HighPrecision (double value); - - int64_t GetHigh (void) const; - int64_t GetLow (void) const; - double GetDouble (void) const; - bool Add (HighPrecision const &o); - bool Sub (HighPrecision const &o); - bool Mul (HighPrecision const &o); - bool Div (HighPrecision const &o); - - int Compare (HighPrecision const &o) const; - static HighPrecision Zero (void); -private: - static const double MAX_64; - double m_value; -}; - -#endif /* HIGH_PRECISION_I128 */ - HighPrecision Abs (HighPrecision const &value); HighPrecision Max (HighPrecision const &a, HighPrecision const &b); HighPrecision Min (HighPrecision const &a, HighPrecision const &b);