| author | |
| committer | |
| log | 3543f283208951514c0fdb45b0dde7393e5e40c7 |
| tree | bf1b41d57db171388b42e827a0e96c05175b7ef0 |
| parent | 3929cac154d71a3e19fd028fc67c1d1d15823ca2 |
Closes #21311
The sign of the result `r` needs to be initialized before the correction
`r.addScalar(r.toConst(), -1)`, or the intended end result could be off
by 2 (depending on the original sign of `r`).2 files changed, 10 insertions(+), 1 deletions(-)
lib/std/math/big/int.zig+1-1| ... | ... | @@ -1202,6 +1202,7 @@ pub const Mutable = struct { |
| 1202 | 1202 | llshr(r.limbs[0..], a.limbs[0..a.limbs.len], shift); |
| 1203 | 1203 | |
| 1204 | 1204 | r.len = a.limbs.len - full_limbs_shifted_out; |
| 1205 | r.positive = a.positive; | |
| 1205 | 1206 | if (nonzero_negative_shiftout) { |
| 1206 | 1207 | if (full_limbs_shifted_out > 0) { |
| 1207 | 1208 | r.limbs[a.limbs.len - full_limbs_shifted_out] = 0; |
| ... | ... | @@ -1210,7 +1211,6 @@ pub const Mutable = struct { |
| 1210 | 1211 | r.addScalar(r.toConst(), -1); |
| 1211 | 1212 | } |
| 1212 | 1213 | r.normalize(r.len); |
| 1213 | r.positive = a.positive; | |
| 1214 | 1214 | } |
| 1215 | 1215 | |
| 1216 | 1216 | /// r = ~a under 2s complement wrapping semantics. |
lib/std/math/big/int_test.zig+9| ... | ... | @@ -2083,6 +2083,15 @@ test "shift-right negative" { |
| 2083 | 2083 | try a.shiftRight(&a, 1); |
| 2084 | 2084 | a.setSign(true); |
| 2085 | 2085 | try testing.expect(try a.to(u64) == 0x8000000000000000); |
| 2086 | ||
| 2087 | var arg7 = try Managed.initSet(testing.allocator, -32767); | |
| 2088 | defer arg7.deinit(); | |
| 2089 | a.setSign(false); | |
| 2090 | try a.shiftRight(&arg7, 4); | |
| 2091 | try testing.expect(try a.to(i16) == -2048); | |
| 2092 | a.setSign(true); | |
| 2093 | try a.shiftRight(&arg7, 4); | |
| 2094 | try testing.expect(try a.to(i16) == -2048); | |
| 2086 | 2095 | } |
| 2087 | 2096 | |
| 2088 | 2097 | test "sat shift-left simple unsigned" { |