@@ -12,8 +12,152 @@ internal fun Long.clampToInt(): Int =
12
12
else -> toInt()
13
13
}
14
14
15
+ internal const val NANOS_PER_MILLI = 1_000_000
16
+ internal const val MILLIS_PER_ONE = 1_000
17
+ internal const val NANOS_PER_ONE = 1_000_000_000
15
18
16
19
internal expect fun safeMultiply (a : Long , b : Long ): Long
17
20
internal expect fun safeMultiply (a : Int , b : Int ): Int
18
21
internal expect fun safeAdd (a : Long , b : Long ): Long
19
22
internal expect fun safeAdd (a : Int , b : Int ): Int
23
+
24
+ /* * Multiplies two non-zero long values. */
25
+ internal fun safeMultiplyOrZero (a : Long , b : Long ): Long {
26
+ when (b) {
27
+ - 1L -> {
28
+ if (a == Long .MIN_VALUE ) {
29
+ return 0L
30
+ }
31
+ return - a
32
+ }
33
+ 1L -> return a
34
+ }
35
+ val total = a * b
36
+ if (total / b != a) {
37
+ return 0L
38
+ }
39
+ return total
40
+ }
41
+
42
+ /* *
43
+ * Calculates [a] * [b] / [c]. Returns a pair of the quotient and the remainder.
44
+ * [c] must be greater than zero.
45
+ *
46
+ * @throws ArithmeticException if the result overflows a long
47
+ */
48
+ internal fun multiplyAndDivide (a : Long , b : Long , c : Long ): DivRemResult {
49
+ if (a == 0L || b == 0L ) return DivRemResult (0 , 0 )
50
+ val ab = safeMultiplyOrZero(a, b)
51
+ if (ab != 0L ) return DivRemResult (ab / c, ab % c)
52
+
53
+ /* Not just optimizations: this is needed for multiplyAndDivide(Long.MIN_VALUE, x, x) to work. */
54
+ if (b == c) return DivRemResult (a, 0 )
55
+ if (a == c) return DivRemResult (b, 0 )
56
+
57
+
58
+ /* a * b = (ae * 2^64 + ah * 2^32 + al) * (be * 2^64 + bh * 2^32 + bl)
59
+ = ae * be * 2^128 + (ae * bh + ah * be) * 2^96 + (ae * bl + ah * bh + al * be) * 2^64
60
+ + (ah * bl + al * bh) * 2^32 + al * bl
61
+ = 0 + w * 2^96 + x * 2^64 + y * 2^32 + z = xh * 2^96 + (xl + yh) * 2^64 + (yl + zh) * 2^32 + zl
62
+ = r1 * 2^96 | r2 * 2^64 | r3 * 2^32 | r4
63
+ = abh * 2^64 | abl */
64
+ // a, b in [0; 2^64)
65
+
66
+ // sign extensions to 128 bits:
67
+ val ae = if (a >= 0 ) 0L else - 1L // all ones or all zeros
68
+ val be = if (b >= 0 ) 0L else - 1L // all ones or all zeros
69
+
70
+ val al = low(a) // [0; 2^32)
71
+ val ah = high(a) // [0; 2^32)
72
+ val bl = low(b) // [0; 2^32)
73
+ val bh = high(b) // [0; 2^32)
74
+
75
+ /* even though the language operates on signed Long values, we can add and multiply them as if they were unsigned
76
+ due to the fact that they are encoded as 2's complement (hence the need to use sign extensions). The only operation
77
+ here where sign matters is division. */
78
+ val w = ae * bh + ah * be // we will only use the lower 32 bits of this value, so overflow is fine
79
+ val x = ae * bl + ah * bh + al * be // may overflow, but overflow here goes beyond 128 bit
80
+ val y1 = ah * bl
81
+ val y2 = al * bh // y is split into y1 and y2 because y1 + y2 may overflow 2^64, which loses information
82
+ val z = al * bl
83
+
84
+ val r4 = low(z)
85
+ val r3c = low(y1) + low(y2) + high(z)
86
+ val r3 = low(r3c)
87
+ val r2c = high(r3c) + low(x) + high(y1) + high(y2)
88
+ val r2 = low(r2c)
89
+ /* If r1 overflows 2^32 - 1, it's because of sign extension: we don't lose any significant bits because multiplying
90
+ [0; 2^64) by [0; 2^64) may never exceed 2^128 - 1. */
91
+ val r1 = high(r2c) + high(x) + low(w)
92
+
93
+ var abl = (r3 shl 32 ) or r4 // low 64 bits of a * b
94
+ var abh = (r1 shl 32 ) or r2 // high 64 bits of a * b
95
+
96
+
97
+ val sign = if (indexBit(abh, 63 ) == 1L ) - 1 else 1
98
+
99
+ if (sign == - 1 ) {
100
+ // negate, so that we operate on a positive number
101
+ abl = abl.inv () + 1
102
+ abh = abh.inv ()
103
+ if (abl == 0L ) // abl overflowed
104
+ abh + = 1
105
+ }
106
+
107
+ /* The resulting quotient. This division is unsigned, so if the result doesn't fit in 63 bits, it means that
108
+ overflow occurred. */
109
+ var q = 0L
110
+ // The remainder, always less than c and so fits in a Long.
111
+ var r = 0L
112
+ // Simple long division algorithm
113
+ for (bitNo in 127 downTo 0 ) {
114
+ // bit #bitNo of the numerator
115
+ val nextBit = if (bitNo < 64 ) indexBit(abl, bitNo) else indexBit(abh, bitNo - 64 )
116
+ // left-shift R by one bit, setting the least significant bit to nextBit
117
+ r = (r shl 1 ) or nextBit
118
+ // if (R >= c). If R < 0, R >= 2^63 > Long.MAX_VALUE >= c
119
+ if (r >= c || r < 0 ) {
120
+ r - = c
121
+ // set bit #bitNo of Q to 1
122
+ if (bitNo < 63 )
123
+ q = q or (1L shl bitNo)
124
+ else
125
+ throw ArithmeticException (" The result of a multiplication followed by division overflows a long" )
126
+ }
127
+ }
128
+ return DivRemResult (sign * q, sign * r)
129
+ }
130
+
131
+ internal class DivRemResult (val q : Long , val r : Long ) {
132
+ operator fun component1 (): Long = q
133
+ operator fun component2 (): Long = r
134
+ }
135
+
136
+ private inline fun low (x : Long ) = x and 0xffffffff
137
+ private inline fun high (x : Long ) = (x shr 32 ) and 0xffffffff
138
+ /* * For [bit] in [0; 63], return bit #[bit] of [value], counting from the least significant bit */
139
+ private inline fun indexBit (value : Long , bit : Int ): Long = (value shr bit and 1 )
140
+
141
+
142
+ /* *
143
+ * Calculates ([d] * [n] + [r]) / [m], where [n], [m] > 0 and |[r]| <= [n].
144
+ *
145
+ * @throws ArithmeticException if the result overflows a long
146
+ */
147
+ internal fun multiplyAddAndDivide (d : Long , n : Long , r : Long , m : Long ): Long {
148
+ var md = d
149
+ var mr = r
150
+ // make sure [md] and [mr] have the same sign
151
+ if (d > 0 && r < 0 ) {
152
+ md--
153
+ mr + = n
154
+ } else if (d < 0 && r > 0 ) {
155
+ md++
156
+ mr - = n
157
+ }
158
+ if (md == 0L ) {
159
+ return mr / m
160
+ }
161
+ val (rd, rr) = multiplyAndDivide(md, n, m)
162
+ return safeAdd(rd, safeAdd(mr / m, safeAdd(mr % m, rr) / m))
163
+ }
0 commit comments