@@ -137,45 +137,33 @@ pub fn mul_128(x Uint128, y Uint128) (Uint128, Uint128) {
137137}
138138
139139// div_128 returns u / v
140- pub fn div_128 (hi Uint128 , lo Uint128 , y_ Uint128 ) (Uint128 , Uint128 ) {
141- mut y := y_
142- if y.is_zero () {
143- panic ('integer divide by zero' )
140+ pub fn div_128 (a_hi Uint128 , a_lo Uint128 , b Uint128 ) (Uint128 , Uint128 ) {
141+ a := uint256_new (a_lo, a_hi)
142+ b_256 := uint256_new (b, uint128_ zero)
143+ if a < b_256 {
144+ return uint128_ zero, a_lo
144145 }
145-
146- if y.cmp (hi) < = 0 {
147- panic ('integer overflow' )
146+ if b.is_zero () {
147+ panic ('Division by zero' )
148148 }
149-
150- s := u32 (y.leading_zeros ())
151- y = y.lsh (s)
152-
153- un32 := hi.lsh (s).or_ (lo.rsh (128 - s))
154- un10 := lo.lsh (s)
155- mut q1 , rhat := un32 .quo_rem_64 (y.hi)
156- mut r1 := uint128_from_64 (rhat)
157- tmp := Uint128 {r1 .lo, un10 .hi}
158- for q1 .hi != 0 || q1 .mul_64 (y.lo).cmp (tmp) > 0 {
159- q1 = q1 .sub_64 (1 )
160- r1 = r1 .add_64 (y.hi)
161- if r1 .hi != 0 {
162- break
163- }
149+ if a.hi.is_zero () {
150+ return a.lo.quo_rem (b)
164151 }
152+ shift := u32 (b_256 .leading_zeros () - a.leading_zeros ())
153+ mut af := a
154+ mut bf := b_256 .lsh (shift)
155+ mut quotient := uint128_ zero
165156
166- un21 := Uint128 {un32 .lo, un10 .hi}.sub (q1 .mul (y))
167- mut q0 , rhat2 := un21 .quo_rem_64 (y.hi)
168- mut r0 := uint128_from_64 (rhat2 )
169- tmp2 := Uint128 {r0 .lo, un10 .lo}
170- for q0 .hi != 0 || q0 .mul_64 (y.lo).cmp (tmp2 ) > 0 {
171- q0 = q0 .sub_64 (1 )
172- r0 = r0 .add_64 (y.hi)
173- if r0 .hi != 0 {
174- break
175- }
157+ for _ in 0 .. shift + 1 {
158+ quotient = quotient.lsh (1 )
159+ diff_result := bf.add (af.not ())
160+ s := u64 (i64 (diff_result.hi.hi) >> 63 )
161+ quotient.lo |= s & 1
162+ mask := uint256_new (uint128_new (s, s), uint128_new (s, s))
163+ af = af.sub (bf.and (mask))
164+ bf = bf.rsh (1 )
176165 }
177-
178- return Uint128 {q1 .lo, q0 .lo}, Uint128 {un21 .lo, un10 .lo}.sub (q0 .mul (y)).rsh (s)
166+ return quotient, af.lo
179167}
180168
181169// add_64 returns u + v with wraparound semantics
0 commit comments