src/core/model/int64x64-128.cc
author Peter D. Barnes, Jr. <barnes26@llnl.gov>
Sun, 02 Mar 2014 01:02:23 -0800
changeset 10637 67601c471c22
parent 10597 6e1bd685bcaa
child 10968 2d29fee2b7b8
permissions -rw-r--r--
[Bug 1856] int64x64_t double conversions
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7039
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 7032
diff changeset
     1
#include "int64x64-128.h"
7383
c5e131450339 remove ns3/ prefix which is un-needed now that all files are in same module.
Mathieu Lacage <mathieu.lacage@gmail.com>
parents: 7252
diff changeset
     2
#include "abort.h"
c5e131450339 remove ns3/ prefix which is un-needed now that all files are in same module.
Mathieu Lacage <mathieu.lacage@gmail.com>
parents: 7252
diff changeset
     3
#include "assert.h"
9134
7a750f032acd Clean up function logging of core module.
Maja Grubišić <maja.grubisic@live.com>
parents: 7742
diff changeset
     4
#include "log.h"
7a750f032acd Clean up function logging of core module.
Maja Grubišić <maja.grubisic@live.com>
parents: 7742
diff changeset
     5
9191
f094300690db bug 1549: remove logging statements causing stack overflows
Tom Henderson <tomh@tomh.org>
parents: 9134
diff changeset
     6
// Note:  Logging in this file is largely avoided due to the
f094300690db bug 1549: remove logging statements causing stack overflows
Tom Henderson <tomh@tomh.org>
parents: 9134
diff changeset
     7
// number of calls that are made to these functions and the possibility
f094300690db bug 1549: remove logging statements causing stack overflows
Tom Henderson <tomh@tomh.org>
parents: 9134
diff changeset
     8
// of causing recursions leading to stack overflow
f094300690db bug 1549: remove logging statements causing stack overflows
Tom Henderson <tomh@tomh.org>
parents: 9134
diff changeset
     9
9134
7a750f032acd Clean up function logging of core module.
Maja Grubišić <maja.grubisic@live.com>
parents: 7742
diff changeset
    10
NS_LOG_COMPONENT_DEFINE ("int64x64-128");
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    11
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    12
namespace ns3 {
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    13
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    14
static inline  
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    15
bool
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    16
output_sign (const int128_t sa,
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    17
             const int128_t sb,
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    18
             uint128_t & ua,
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    19
             uint128_t & ub)
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    20
{
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    21
  bool negA = sa < 0;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    22
  bool negB = sb < 0;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    23
  ua = negA ? -sa : sa;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    24
  ub = negB ? -sb : sb;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    25
  return (negA && !negB) || (!negA && negB);
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    26
}
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    27
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    28
void
10637
67601c471c22 [Bug 1856] int64x64_t double conversions
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 10597
diff changeset
    29
int64x64_t::Mul (const int64x64_t & o)
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    30
{
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    31
  uint128_t a, b;
10637
67601c471c22 [Bug 1856] int64x64_t double conversions
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 10597
diff changeset
    32
  bool negative = output_sign (_v, o._v, a, b);
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    33
  uint128_t result = Umul (a, b);
10637
67601c471c22 [Bug 1856] int64x64_t double conversions
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 10597
diff changeset
    34
  _v = negative ? -result : result;
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    35
}
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    36
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    37
uint128_t
10637
67601c471c22 [Bug 1856] int64x64_t double conversions
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 10597
diff changeset
    38
int64x64_t::Umul (const uint128_t a, const uint128_t b)
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    39
{
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    40
  uint128_t aL = a & HP_MASK_LO;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    41
  uint128_t bL = b & HP_MASK_LO;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    42
  uint128_t aH = (a >> 64) & HP_MASK_LO;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    43
  uint128_t bH = (b >> 64) & HP_MASK_LO;
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    44
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    45
  uint128_t result;
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    46
  uint128_t hiPart, loPart, midPart;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    47
  uint128_t res1, res2;
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    48
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    49
  // Multiplying (a.h 2^64 + a.l) x (b.h 2^64 + b.l) =
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    50
  //			2^128 a.h b.h + 2^64*(a.h b.l+b.h a.l) + a.l b.l
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    51
  // get the low part a.l b.l
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    52
  // multiply the fractional part
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    53
  loPart = aL * bL;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    54
  // compute the middle part 2^64*(a.h b.l+b.h a.l)
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    55
  midPart = aL * bH + aH * bL;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    56
  // compute the high part 2^128 a.h b.h
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    57
  hiPart = aH * bH;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    58
  // if the high part is not zero, put a warning
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    59
  NS_ABORT_MSG_IF ((hiPart & HP_MASK_HI) != 0,
7169
358f71a624d8 core coding style changes
Josh Pelkey <jpelkey@gatech.edu>
parents: 7104
diff changeset
    60
                   "High precision 128 bits multiplication error: multiplication overflow.");
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    61
  
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    62
  // Adding 64-bit terms to get 128-bit results, with carries
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    63
  res1 = loPart >> 64;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    64
  res2 = midPart & HP_MASK_LO;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    65
  result = res1 + res2;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    66
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    67
  res1 = midPart >> 64;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    68
  res2 = hiPart & HP_MASK_LO;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    69
  res1 += res2;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    70
  res1 <<= 64;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    71
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    72
  result += res1;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    73
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    74
  return result;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    75
}
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    76
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    77
void
10637
67601c471c22 [Bug 1856] int64x64_t double conversions
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 10597
diff changeset
    78
int64x64_t::Div (const int64x64_t & o)
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    79
{
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    80
  uint128_t a, b;
10637
67601c471c22 [Bug 1856] int64x64_t double conversions
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 10597
diff changeset
    81
  bool negative = output_sign (_v, o._v, a, b);
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    82
  int128_t result = Udiv (a, b);
10637
67601c471c22 [Bug 1856] int64x64_t double conversions
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 10597
diff changeset
    83
  _v = negative ? -result : result;
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    84
}
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    85
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    86
uint128_t
10637
67601c471c22 [Bug 1856] int64x64_t double conversions
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 10597
diff changeset
    87
int64x64_t::Udiv (const uint128_t a, const uint128_t b)
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    88
{
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    89
  
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    90
  uint128_t rem = a;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    91
  uint128_t den = b;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    92
  uint128_t quo = rem / den;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    93
  rem = rem % den;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    94
  uint128_t result = quo;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    95
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    96
  // Now, manage the remainder
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    97
  const uint64_t DIGITS = 64;  // Number of fraction digits (bits) we need
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    98
  const uint128_t ZERO = 0;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
    99
  
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   100
  NS_ASSERT_MSG (rem < den,
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   101
                 "Remainder not less than divisor");
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   102
  
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   103
  uint64_t digis = 0;          // Number of digits we have already
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   104
  uint64_t shift = 0;          // Number we are going to get this round
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   105
  
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   106
    // Skip trailing zeros in divisor
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   107
  while ( (shift < DIGITS) && !(den & 0x1))
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   108
    {
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   109
      ++shift;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   110
      den >>= 1;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   111
    }
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   112
  
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   113
  while ( (digis < DIGITS) && (rem != ZERO) )
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   114
    {
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   115
      // Skip leading zeros in remainder
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   116
      while ( (digis + shift < DIGITS) &&
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   117
              !(rem & HP128_MASK_HI_BIT))
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   118
        {      
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   119
          ++shift;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   120
          rem <<= 1;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   121
        }
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   122
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   123
      // Cast off denominator bits if:
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   124
      //   Need more digits and
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   125
      //     LSB is zero or 
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   126
      //     rem < den
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   127
      while ( (digis + shift < DIGITS) &&
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   128
              ( !(den & 0x1) || (rem < den) ) )
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   129
        {
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   130
          ++shift;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   131
          den >>= 1;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   132
        }
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   133
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   134
      // Do the division
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   135
      quo = rem / den;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   136
      rem = rem % den;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   137
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   138
      // Add in the quotient as shift bits of the fraction
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   139
      result <<= shift;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   140
      result += quo;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   141
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   142
      digis += shift;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   143
      shift = 0;
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   144
    }
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   145
  // Did we run out of remainder?
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   146
  if (digis < DIGITS)
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   147
    {
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   148
      shift = DIGITS - digis;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   149
      result <<= shift;
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   150
    }
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   151
  
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   152
  return result;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   153
}
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   154
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   155
void 
10637
67601c471c22 [Bug 1856] int64x64_t double conversions
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 10597
diff changeset
   156
int64x64_t::MulByInvert (const int64x64_t & o)
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   157
{
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   158
  bool negResult = _v < 0;
7169
358f71a624d8 core coding style changes
Josh Pelkey <jpelkey@gatech.edu>
parents: 7104
diff changeset
   159
  uint128_t a = negResult ? -_v : _v;
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   160
  uint128_t result = UmulByInvert (a, o._v);
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   161
7169
358f71a624d8 core coding style changes
Josh Pelkey <jpelkey@gatech.edu>
parents: 7104
diff changeset
   162
  _v = negResult ? -result : result;
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   163
}
10637
67601c471c22 [Bug 1856] int64x64_t double conversions
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 10597
diff changeset
   164
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   165
uint128_t
10637
67601c471c22 [Bug 1856] int64x64_t double conversions
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 10597
diff changeset
   166
int64x64_t::UmulByInvert (const uint128_t a, const uint128_t b)
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   167
{
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   168
  uint128_t result, ah, bh, al, bl;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   169
  uint128_t hi, mid;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   170
  ah = a >> 64;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   171
  bh = b >> 64;
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   172
  al = a & HP_MASK_LO;
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   173
  bl = b & HP_MASK_LO;
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   174
  hi = ah * bh;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   175
  mid = ah * bl + al * bh;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   176
  mid >>= 64;
7104
875b31cb83e0 typo caught by gcc 4.6.0 reported by John Abraham
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 7045
diff changeset
   177
  result = hi + mid;
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   178
  return result;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   179
}
10637
67601c471c22 [Bug 1856] int64x64_t double conversions
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 10597
diff changeset
   180
7039
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 7032
diff changeset
   181
int64x64_t 
10637
67601c471c22 [Bug 1856] int64x64_t double conversions
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 10597
diff changeset
   182
int64x64_t::Invert (const uint64_t v)
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   183
{
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   184
  NS_ASSERT (v > 1);
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   185
  uint128_t a;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   186
  a = 1;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   187
  a <<= 64;
7039
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 7032
diff changeset
   188
  int64x64_t result;
10597
6e1bd685bcaa [Bug 1786] Fix for os << (int64x64_t) and fractional arithmetic
Peter D. Barnes, Jr. <barnes26@llnl.gov>
parents: 9191
diff changeset
   189
  result._v = Udiv (a, v);
7039
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 7032
diff changeset
   190
  int64x64_t tmp = int64x64_t (v, false);
7032
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   191
  tmp.MulByInvert (result);
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   192
  if (tmp.GetHigh () != 1)
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   193
    {
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   194
      result._v += 1;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   195
    }
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   196
  return result;
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   197
}
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   198
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   199
} // namespace ns3
17d4c8f349d6 split out uint64x64 type, optimize
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
   200