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-- |
7039 | 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 | 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 | 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 | 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 |