| ... | ... | @@ -525,9 +525,7 @@ pub const Mutable = struct { |
| 525 | 525 | } |
| 526 | 526 | |
| 527 | 527 | // Saturate if the result didn't fit. |
| 528 | | if (!r.toConst().fitsInTwosComp(signedness, bit_count)) { |
| 529 | | r.setTwosCompIntLimit(if (r.positive) .max else .min, signedness, bit_count); |
| 530 | | } |
| 528 | r.saturate(r.toConst(), signedness, bit_count); |
| 531 | 529 | } |
| 532 | 530 | |
| 533 | 531 | /// Base implementation for subtraction. Subtracts `max(a.limbs.len, b.limbs.len)` elements from a and b, |
| ... | ... | @@ -661,7 +659,7 @@ pub const Mutable = struct { |
| 661 | 659 | } |
| 662 | 660 | } |
| 663 | 661 | |
| 664 | | mem.set(Limb, rma.limbs[0 .. a.limbs.len + b.limbs.len + 1], 0); |
| 662 | mem.set(Limb, rma.limbs[0 .. a.limbs.len + b.limbs.len], 0); |
| 665 | 663 | |
| 666 | 664 | llmulacc(.add, allocator, rma.limbs, a.limbs, b.limbs); |
| 667 | 665 | |
| ... | ... | @@ -1366,6 +1364,17 @@ pub const Mutable = struct { |
| 1366 | 1364 | } |
| 1367 | 1365 | } |
| 1368 | 1366 | |
| 1367 | /// Saturate an integer to a number of bits, following 2s-complement semantics. |
| 1368 | /// r may alias a. |
| 1369 | /// |
| 1370 | /// Asserts `r` has enough storage to store the result. |
| 1371 | /// The upper bound is `calcTwosCompLimbCount(a.len)`. |
| 1372 | pub fn saturate(r: *Mutable, a: Const, signedness: std.builtin.Signedness, bit_count: usize) void { |
| 1373 | if (!a.fitsInTwosComp(signedness, bit_count)) { |
| 1374 | r.setTwosCompIntLimit(if (r.positive) .max else .min, signedness, bit_count); |
| 1375 | } |
| 1376 | } |
| 1377 | |
| 1369 | 1378 | /// Normalize a possible sequence of leading zeros. |
| 1370 | 1379 | /// |
| 1371 | 1380 | /// [1, 2, 3, 4, 0] -> [1, 2, 3, 4] |
| ... | ... | @@ -2414,6 +2423,14 @@ pub const Managed = struct { |
| 2414 | 2423 | m.truncate(a, signedness, bit_count); |
| 2415 | 2424 | r.setMetadata(m.positive, m.len); |
| 2416 | 2425 | } |
| 2426 | |
| 2427 | /// r = saturate(Int(signedness, bit_count), a) |
| 2428 | pub fn saturate(r: *Managed, a: Const, signedness: std.builtin.Signedness, bit_count: usize) !void { |
| 2429 | try r.ensureCapacity(calcTwosCompLimbCount(bit_count)); |
| 2430 | var m = r.toMutable(); |
| 2431 | m.saturate(a, signedness, bit_count); |
| 2432 | r.setMetadata(m.positive, m.len); |
| 2433 | } |
| 2417 | 2434 | }; |
| 2418 | 2435 | |
| 2419 | 2436 | /// Different operators which can be used in accumulation style functions |