@@ -21,14 +21,21 @@ reversed_index(n::Int, i::Int) = n - i - 1
2121reversed_index (x, i:: Int , v:: Val ) = reversed_index (elem_count (x, v), i):: Int
2222split_bit_index (x:: RawBigInt , i:: Int ) = divrem (i, word_length (x), RoundToZero)
2323
24+ function get_elem_words_raw (x:: RawBigInt{T} , i:: Int ) where {T}
25+ @boundscheck if (i < 0 ) || (elem_count (x, Val (:words )) ≤ i)
26+ throw (BoundsError (x, i))
27+ end
28+ d = x. d
29+ j = i + 1
30+ (GC. @preserve d unsafe_load (Ptr {T} (pointer (d)), j)):: T
31+ end
32+
2433"""
2534`i` is the zero-based index of the wanted word in `x`, starting from
2635the less significant words.
2736"""
28- function get_elem (x:: RawBigInt{T} , i:: Int , :: Val{:words} , :: Val{:ascending} ) where {T}
29- # `i` must be non-negative and less than `x.word_count`
30- d = x. d
31- (GC. @preserve d unsafe_load (Ptr {T} (pointer (d)), i + 1 )):: T
37+ function get_elem (x:: RawBigInt , i:: Int , :: Val{:words} , :: Val{:ascending} )
38+ @inbounds @inline get_elem_words_raw (x, i)
3239end
3340
3441function get_elem (x, i:: Int , v:: Val , :: Val{:descending} )
96103
97104"""
98105Returns an integer of type `R`, consisting of the `len` most
99- significant bits of `x`.
106+ significant bits of `x`. If there are less than `len` bits in `x`,
107+ the least significant bits are zeroed.
100108"""
101109function truncated (:: Type{R} , x:: RawBigInt , len:: Int ) where {R<: Integer }
102110 ret = zero (R)
103111 if 0 < len
104112 word_count, bit_count_in_word = split_bit_index (x, len)
105113 k = word_length (x)
106114 vals = (Val (:words ), Val (:descending ))
115+ lenx = elem_count (x, first (vals))
107116
108117 for w ∈ 0 : (word_count - 1 )
109118 ret <<= k
110- word = get_elem (x, w, vals... )
111- ret |= R (word)
119+ if w < lenx
120+ word = get_elem (x, w, vals... )
121+ ret |= R (word)
122+ end
112123 end
113124
114125 if ! iszero (bit_count_in_word)
115126 ret <<= bit_count_in_word
116- wrd = get_elem (x, word_count, vals... )
117- ret |= R (wrd >>> (k - bit_count_in_word))
127+ if word_count < lenx
128+ wrd = get_elem (x, word_count, vals... )
129+ ret |= R (wrd >>> (k - bit_count_in_word))
130+ end
118131 end
119132 end
120133 ret:: R
0 commit comments