authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-03 16:34:52+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-04 11:25:29+02:00
logbbd50248f25996e707ebacc2f020e23cee6140e3
tree764ecaa9dfa25e655daf00cf2596e93cb2f99f80
parentfdf13fb81940ada1673914cab4ff46a1ddae42dd

big ints: saturate() function


1 files changed, 21 insertions(+), 4 deletions(-)

lib/std/math/big/int.zig+21-4
......@@ -525,9 +525,7 @@ pub const Mutable = struct {
525525 }
526526
527527 // 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);
531529 }
532530
533531 /// 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 {
661659 }
662660 }
663661
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);
665663
666664 llmulacc(.add, allocator, rma.limbs, a.limbs, b.limbs);
667665
......@@ -1366,6 +1364,17 @@ pub const Mutable = struct {
13661364 }
13671365 }
13681366
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
13691378 /// Normalize a possible sequence of leading zeros.
13701379 ///
13711380 /// [1, 2, 3, 4, 0] -> [1, 2, 3, 4]
......@@ -2414,6 +2423,14 @@ pub const Managed = struct {
24142423 m.truncate(a, signedness, bit_count);
24152424 r.setMetadata(m.positive, m.len);
24162425 }
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 }
24172434};
24182435
24192436/// Different operators which can be used in accumulation style functions