mirror of
https://github.com/ziglang/zig.git
synced 2026-02-05 14:07:04 +00:00
big.int: 2s-complement binary wrapping not
This commit is contained in:
parent
98a37dfb23
commit
6a3659c4e0
@ -825,7 +825,7 @@ pub const Mutable = struct {
|
||||
///
|
||||
/// Asserts there is enough memory to fit the result. The upper bound Limb count is
|
||||
/// r is `calcTwosCompLimbCount(bit_count)`.
|
||||
pub fn shiftLeftSat(r: *Mutable, a: Const, shift: usize, signedness: std.builtin.Signedness, bit_count: usize) void {
|
||||
pub fn shiftLeftSat(r: *Mutable, a: Const, shift: usize, signedness: Signedness, bit_count: usize) void {
|
||||
// Special case: When the argument is negative, but the result is supposed to be unsigned,
|
||||
// return 0 in all cases.
|
||||
if (!a.positive and signedness == .unsigned) {
|
||||
@ -906,6 +906,17 @@ pub const Mutable = struct {
|
||||
r.positive = a.positive;
|
||||
}
|
||||
|
||||
/// r = ~a under 2s complement wrapping semantics.
|
||||
/// r may alias with a.
|
||||
///
|
||||
/// Assets that r has enough limbs to store the result. The upper bound Limb count is
|
||||
/// r is `calcTwosCompLimbCount(bit_count)`.
|
||||
pub fn bitNotWrap(r: *Mutable, a: Const, signedness: Signedness, bit_count: usize) void {
|
||||
r.copy(a.negate());
|
||||
const negative_one = Const{ .limbs = &.{1}, .positive = false };
|
||||
r.addWrap(r.toConst(), negative_one, signedness, bit_count);
|
||||
}
|
||||
|
||||
/// r = a | b under 2s complement semantics.
|
||||
/// r may alias with a or b.
|
||||
///
|
||||
@ -2455,7 +2466,7 @@ pub const Managed = struct {
|
||||
}
|
||||
|
||||
/// r = a <<| shift with 2s-complement saturating semantics.
|
||||
pub fn shiftLeftSat(r: *Managed, a: Managed, shift: usize, signedness: std.builtin.Signedness, bit_count: usize) !void {
|
||||
pub fn shiftLeftSat(r: *Managed, a: Managed, shift: usize, signedness: Signedness, bit_count: usize) !void {
|
||||
try r.ensureTwosCompCapacity(bit_count);
|
||||
var m = r.toMutable();
|
||||
m.shiftLeftSat(a.toConst(), shift, signedness, bit_count);
|
||||
@ -2476,6 +2487,14 @@ pub const Managed = struct {
|
||||
r.setMetadata(m.positive, m.len);
|
||||
}
|
||||
|
||||
/// r = ~a under 2s-complement wrapping semantics.
|
||||
pub fn bitNotWrap(r: *Managed, a: Managed, signedness: Signedness, bit_count: usize) !void {
|
||||
try r.ensureTwosCompCapacity(bit_count);
|
||||
var m = r.toMutable();
|
||||
m.bitNotWrap(a.toConst(), signedness, bit_count);
|
||||
r.setMetadata(m.positive, m.len);
|
||||
}
|
||||
|
||||
/// r = a | b
|
||||
///
|
||||
/// a and b are zero-extended to the longer of a or b.
|
||||
|
||||
@ -1866,6 +1866,42 @@ test "big.int sat shift-left signed multi negative" {
|
||||
try testing.expect((try a.to(SignedDoubleLimb)) == @as(SignedDoubleLimb, x) <<| shift);
|
||||
}
|
||||
|
||||
test "big.int bitNotWrap unsigned simple" {
|
||||
var a = try Managed.initSet(testing.allocator, 123);
|
||||
defer a.deinit();
|
||||
|
||||
try a.bitNotWrap(a, .unsigned, 10);
|
||||
|
||||
try testing.expect((try a.to(u10)) == ~@as(u10, 123));
|
||||
}
|
||||
|
||||
test "big.int bitNotWrap unsigned multi" {
|
||||
var a = try Managed.initSet(testing.allocator, 0);
|
||||
defer a.deinit();
|
||||
|
||||
try a.bitNotWrap(a, .unsigned, @bitSizeOf(DoubleLimb));
|
||||
|
||||
try testing.expect((try a.to(DoubleLimb)) == maxInt(DoubleLimb));
|
||||
}
|
||||
|
||||
test "big.int bitNotWrap signed simple" {
|
||||
var a = try Managed.initSet(testing.allocator, -456);
|
||||
defer a.deinit();
|
||||
|
||||
try a.bitNotWrap(a, .signed, 11);
|
||||
|
||||
try testing.expect((try a.to(i11)) == ~@as(i11, -456));
|
||||
}
|
||||
|
||||
test "big.int bitNotWrap signed multi" {
|
||||
var a = try Managed.initSet(testing.allocator, 0);
|
||||
defer a.deinit();
|
||||
|
||||
try a.bitNotWrap(a, .signed, @bitSizeOf(SignedDoubleLimb));
|
||||
|
||||
try testing.expect((try a.to(SignedDoubleLimb)) == -1);
|
||||
}
|
||||
|
||||
test "big.int bitwise and simple" {
|
||||
var a = try Managed.initSet(testing.allocator, 0xffffffff11111111);
|
||||
defer a.deinit();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user