|
2 | 2 |
|
3 | 3 | module MultiplicativeInverses
|
4 | 4 |
|
5 |
| -import Base: div, divrem, rem, unsigned |
| 5 | +import Base: div, divrem, mul_hi, rem, unsigned |
6 | 6 | using Base: IndexLinear, IndexCartesian, tail
|
7 | 7 | export multiplicativeinverse
|
8 | 8 |
|
@@ -134,33 +134,13 @@ struct UnsignedMultiplicativeInverse{T<:Unsigned} <: MultiplicativeInverse{T}
|
134 | 134 | end
|
135 | 135 | UnsignedMultiplicativeInverse(x::Unsigned) = UnsignedMultiplicativeInverse{typeof(x)}(x)
|
136 | 136 |
|
137 |
| -# Returns the higher half of the product a*b |
138 |
| -function _mul_high(a::T, b::T) where {T<:Union{Signed, Unsigned}} |
139 |
| - ((widen(a)*b) >>> (sizeof(a)*8)) % T |
140 |
| -end |
141 |
| - |
142 |
| -function _mul_high(a::UInt128, b::UInt128) |
143 |
| - shift = sizeof(a)*4 |
144 |
| - mask = typemax(UInt128) >> shift |
145 |
| - a1, a2 = a >>> shift, a & mask |
146 |
| - b1, b2 = b >>> shift, b & mask |
147 |
| - a1b1, a1b2, a2b1, a2b2 = a1*b1, a1*b2, a2*b1, a2*b2 |
148 |
| - carry = ((a1b2 & mask) + (a2b1 & mask) + (a2b2 >>> shift)) >>> shift |
149 |
| - a1b1 + (a1b2 >>> shift) + (a2b1 >>> shift) + carry |
150 |
| -end |
151 |
| -function _mul_high(a::Int128, b::Int128) |
152 |
| - shift = sizeof(a)*8 - 1 |
153 |
| - t1, t2 = (a >> shift) & b % UInt128, (b >> shift) & a % UInt128 |
154 |
| - (_mul_high(a % UInt128, b % UInt128) - t1 - t2) % Int128 |
155 |
| -end |
156 |
| - |
157 | 137 | function div(a::T, b::SignedMultiplicativeInverse{T}) where T
|
158 |
| - x = _mul_high(a, b.multiplier) |
| 138 | + x = mul_hi(a, b.multiplier) |
159 | 139 | x += (a*b.addmul) % T
|
160 | 140 | ifelse(abs(b.divisor) == 1, a*b.divisor, (signbit(x) + (x >> b.shift)) % T)
|
161 | 141 | end
|
162 | 142 | function div(a::T, b::UnsignedMultiplicativeInverse{T}) where T
|
163 |
| - x = _mul_high(a, b.multiplier) |
| 143 | + x = mul_hi(a, b.multiplier) |
164 | 144 | x = ifelse(b.add, convert(T, convert(T, (convert(T, a - x) >>> 1)) + x), x)
|
165 | 145 | ifelse(b.divisor == 1, a, x >>> b.shift)
|
166 | 146 | end
|
|
0 commit comments