Skip to content

Commit 09e1edb

Browse files
authored
math.unsigned: fix rsh() for uint256 too, add tests (#24865)
1 parent bb7f9f2 commit 09e1edb

2 files changed

Lines changed: 36 additions & 10 deletions

File tree

‎vlib/math/unsigned/uint256.v‎

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -230,17 +230,32 @@ pub fn (u Uint256) quo_rem_64(v u64) (Uint256, u64) {
230230
}
231231

232232
// rsh returns a new Uint256 that has been right bit shifted
233-
pub fn (u Uint256) rsh(n_ u32) Uint256 {
234-
mut n := n_
235-
if n > 128 {
236-
return Uint256{u.hi.rsh(n - 128), uint128_zero}
237-
}
238-
239-
if n > 64 {
240-
n -= 64
241-
return Uint256{Uint128{u.lo.hi >> n | u.hi.lo << (64 - n), u.hi.lo >> n | u.hi.hi << (64 - n)}, Uint128{u.hi.hi >> n, 0}}
233+
pub fn (u Uint256) rsh(n u32) Uint256 {
234+
mut s := Uint256{}
235+
if n == 0 {
236+
s.lo = u.lo
237+
s.hi = u.hi
238+
} else if n >= 256 {
239+
s.lo = uint128_zero
240+
s.hi = uint128_zero
241+
} else if n == 128 {
242+
s.hi = uint128_zero
243+
s.lo = u.hi
244+
} else if n > 128 {
245+
s.hi = uint128_zero
246+
s.lo = u.hi.rsh(n - 128)
247+
} else if n == 64 {
248+
s.lo = Uint128{u.lo.hi, u.hi.lo}
249+
s.hi = Uint128{u.hi.hi, 0}
250+
} else if n > 64 {
251+
shift := n - 64
252+
s.lo = Uint128{u.lo.hi >> shift | u.hi.lo << (64 - shift), u.hi.lo >> shift | u.hi.hi << (64 - shift)}
253+
s.hi = Uint128{u.hi.hi >> shift, 0}
254+
} else {
255+
s.lo = Uint128{u.lo.lo >> n | u.lo.hi << (64 - n), u.lo.hi >> n | u.hi.lo << (64 - n)}
256+
s.hi = Uint128{u.hi.lo >> n | u.hi.hi << (64 - n), u.hi.hi >> n}
242257
}
243-
return Uint256{Uint128{u.lo.lo >> n | u.lo.hi << (64 - n), u.lo.hi >> n | u.hi.lo << (64 - n)}, Uint128{u.hi.lo >> n | u.hi.hi << (64 - n), u.hi.hi >> n}}
258+
return s
244259
}
245260

246261
// lsh returns a new Uint256 that has been left bit shifted

‎vlib/math/unsigned/uint256_test.v‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,3 +280,14 @@ fn test_separators() {
280280
fn test_new() {
281281
assert unsigned.uint256_new(unsigned.uint128_max, unsigned.uint128_max) == unsigned.uint256_max
282282
}
283+
284+
fn test_rsh() {
285+
a := unsigned.uint256_from_dec_str('115792089237316195423570985008687907853269984665640564039457584007913129639935')!
286+
assert a.str() == a.rsh(0).str()
287+
assert '57896044618658097711785492504343953926634992332820282019728792003956564819967' == a.rsh(1).str()
288+
assert '6277101735386680763835789423207666416102355444464034512895' == a.rsh(64).str()
289+
assert '91343852333181432387730302044767688728495783935' == a.rsh(100).str()
290+
assert '340282366920938463463374607431768211455' == a.rsh(128).str()
291+
assert '170141183460469231731687303715884105727' == a.rsh(129).str()
292+
assert unsigned.uint256_zero == a.rsh(256)
293+
}

0 commit comments

Comments
 (0)