View | Details | Raw Unified | Return to bug 533
Collapse All | Expand All

(-)a/src/simulator/high-precision-128.cc (-2 / +78 lines)
 Lines 19-24    Link Here 
19
 */
19
 */
20
#include "high-precision-128.h"
20
#include "high-precision-128.h"
21
#include "ns3/test.h"
21
#include "ns3/test.h"
22
#include "ns3/fatal-error.h"
22
#include <math.h>
23
#include <math.h>
23
#include <iostream>
24
#include <iostream>
24
25
 Lines 151-160    Link Here 
151
{
152
{
152
  EnsureSlow ();
153
  EnsureSlow ();
153
  const_cast<HighPrecision &> (o).EnsureSlow ();
154
  const_cast<HighPrecision &> (o).EnsureSlow ();
154
  cairo_int128_t other = _cairo_int128_rsa (o.m_slowValue, 64);
155
  //use the 128 bits multiplication
155
  m_slowValue = _cairo_int128_mul (m_slowValue, other);
156
  m_slowValue = Mul128(m_slowValue,o.m_slowValue);
156
  return false;
157
  return false;
157
}
158
}
159
/**
160
 * this function multiplies two 128 bits fractions considering
161
 * the high 64 bits as the integer part and the low 64 bits
162
 * as the fractional part. It takes into account the sign
163
 * of the operands to produce a signed 128 bits result.
164
 */
165
cairo_int128_t
166
HighPrecision::Mul128(cairo_int128_t a, cairo_int128_t b )
167
{
168
  //Implement the 128 bits multiplication
169
  cairo_int128_t result;
170
  cairo_uint128_t hiPart,loPart,midPart;
171
  bool resultNegative = false, signA = false,signB = false;
172
173
  //take the sign of the operands
174
  signA = _cairo_int128_negative (a);
175
  signB = _cairo_int128_negative (b);
176
  //the result is negative only if one of the operand is negative
177
  if ((signA == true && signB == false) ||(signA == false && signB == true))
178
    {
179
  	 resultNegative = true;
180
    }
181
  //now take the absolute part to make sure that the resulting operands are positive
182
  if (signA == true)
183
  {
184
	  a = _cairo_int128_negate (a);
185
  }
186
  if (signB == true)
187
  {
188
  	  b = _cairo_int128_negate (b);
189
  }
190
191
  //Multiplying (a.h 2^64 + a.l) x (b.h 2^64 + b.l) =
192
  //			2^128 a.h b.h + 2^64*(a.h b.l+b.h a.l) + a.l b.l
193
  //get the low part a.l b.l
194
  //multiply the fractional part
195
  loPart = _cairo_uint64x64_128_mul (a.lo, b.lo);
196
  //compute the middle part 2^64*(a.h b.l+b.h a.l)
197
  midPart = _cairo_uint128_add(_cairo_uint64x64_128_mul(a.lo, b.hi),
198
		  _cairo_uint64x64_128_mul(a.hi, b.lo)) ;
199
  //truncate the low part
200
  result.lo = _cairo_uint64_add(loPart.hi,midPart.lo);
201
  //compute the high part 2^128 a.h b.h
202
  hiPart = _cairo_uint64x64_128_mul (a.hi, b.hi);
203
  //truncate the high part and only use the low part
204
  result.hi = _cairo_uint64_add(hiPart.lo,midPart.hi);
205
  //if the high part is not zero, put a warning
206
  if (hiPart.hi !=0)
207
  {
208
	  NS_FATAL_ERROR("High precision 128 bits multiplication error: multiplication overflow.");
209
  }
210
  //add the sign to the result
211
  if (resultNegative)
212
  {
213
	 result = _cairo_int128_negate (result);
214
  }
215
  return result;
216
}
217
158
bool 
218
bool 
159
HighPrecision::Div (HighPrecision const &o)
219
HighPrecision::Div (HighPrecision const &o)
160
{
220
{
 Lines 351-356    Link Here 
351
  a = HighPrecision (0.1);
411
  a = HighPrecision (0.1);
352
  a.Div (HighPrecision (1.25));
412
  a.Div (HighPrecision (1.25));
353
  NS_TEST_ASSERT_EQUAL (a.GetDouble (), 0.08);
413
  NS_TEST_ASSERT_EQUAL (a.GetDouble (), 0.08);
414
  //test the multiplication
415
  a = HighPrecision (0.5);
416
  a.Mul(HighPrecision (5));
417
  NS_TEST_ASSERT_EQUAL (a.GetDouble (), 2.5);
418
  //test the sign of multiplication, first operand negative
419
  a = HighPrecision (-0.5);
420
  a.Mul(HighPrecision (5));
421
  NS_TEST_ASSERT_EQUAL (a.GetDouble (), -2.5);
422
  //two negative
423
  a = HighPrecision (-0.5);
424
  a.Mul(HighPrecision (-5));
425
  NS_TEST_ASSERT_EQUAL (a.GetDouble (), 2.5);
426
  //second operand negative
427
  a = HighPrecision (0.5);
428
  a.Mul(HighPrecision (-5));
429
  NS_TEST_ASSERT_EQUAL (a.GetDouble (), -2.5);
354
430
355
431
356
  return result;
432
  return result;
(-)a/src/simulator/high-precision-128.h (+1 lines)
 Lines 85-90    Link Here 
85
  bool SlowSub (HighPrecision const &o);
85
  bool SlowSub (HighPrecision const &o);
86
  bool SlowMul (HighPrecision const &o);
86
  bool SlowMul (HighPrecision const &o);
87
  int SlowCompare (HighPrecision const &o) const;
87
  int SlowCompare (HighPrecision const &o) const;
88
  cairo_uint128_t  Mul128(cairo_uint128_t , cairo_uint128_t );
88
  inline void EnsureSlow (void);
89
  inline void EnsureSlow (void);
89
90
90
  static const double MAX_64;
91
  static const double MAX_64;
(-)a/src/simulator/time.cc (-2 / +2 lines)
 Lines 572-582    Link Here 
572
572
573
  Time t4;
573
  Time t4;
574
  t4 = Seconds (10.0) * Scalar (1.5);
574
  t4 = Seconds (10.0) * Scalar (1.5);
575
  CheckTimeSec("old 11", t4.GetSeconds(), 10, ok);
575
  CheckTimeSec("old 11", t4.GetSeconds(), 15, ok);
576
576
577
  Time t5;
577
  Time t5;
578
  t5 = NanoSeconds (10) * Scalar (1.5);
578
  t5 = NanoSeconds (10) * Scalar (1.5);
579
  CheckTime("old 12", t5.GetNanoSeconds(), 10, ok);
579
  CheckTime("old 12", t5.GetNanoSeconds(), 15, ok);
580
580
581
  t4 = Seconds (10.0) * Scalar (15) / Scalar (10);
581
  t4 = Seconds (10.0) * Scalar (15) / Scalar (10);
582
  CheckTimeSec("old 13", t4.GetSeconds(), 15, ok);
582
  CheckTimeSec("old 13", t4.GetSeconds(), 15, ok);

Return to bug 533