authorgravatar for jahe788@gmail.comIntegratedQuantum <jahe788@gmail.com> 2022-12-14 01:29:25+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-09 15:04:55-07:00
logd6faa4e86893e5c64130deab0fa858abbc41fbf5
tree10538aa73e3bc90f6747142c6f3a6898b7a46f9b
parentf8ea292d0989ac8245399a8dad6f27c8b28cd696

Fix tautological big_int tests.


5 files changed, 68 insertions(+), 37 deletions(-)

lib/std/math/big/int.zig+23-5
......@@ -1176,15 +1176,26 @@ pub const Mutable = struct {
11761176 /// `a.limbs.len - (shift / (@sizeOf(Limb) * 8))`.
11771177 pub fn shiftRight(r: *Mutable, a: Const, shift: usize) void {
11781178 if (a.limbs.len <= shift / limb_bits) {
1179 r.len = 1;
1180 r.positive = true;
1181 r.limbs[0] = 0;
1179 // Shifting negative numbers converges to -1 instead of 0
1180 if (a.positive) {
1181 r.len = 1;
1182 r.positive = true;
1183 r.limbs[0] = 0;
1184 } else {
1185 r.len = 1;
1186 r.positive = false;
1187 r.limbs[0] = 1;
1188 }
11821189 return;
11831190 }
11841191
11851192 llshr(r.limbs[0..], a.limbs[0..a.limbs.len], shift);
11861193 r.normalize(a.limbs.len - (shift / limb_bits));
11871194 r.positive = a.positive;
1195 // Shifting negative numbers converges to -1 instead of 0
1196 if (!r.positive and r.len == 1 and r.limbs[0] == 0) {
1197 r.limbs[0] = 1;
1198 }
11881199 }
11891200
11901201 /// r = ~a under 2s complement wrapping semantics.
......@@ -2900,8 +2911,15 @@ pub const Managed = struct {
29002911 /// r and a may alias.
29012912 pub fn shiftRight(r: *Managed, a: *const Managed, shift: usize) !void {
29022913 if (a.len() <= shift / limb_bits) {
2903 r.metadata = 1;
2904 r.limbs[0] = 0;
2914 // Shifting negative numbers converges to -1 instead of 0
2915 if (a.isPositive()) {
2916 r.metadata = 1;
2917 r.limbs[0] = 0;
2918 } else {
2919 r.metadata = 1;
2920 r.setSign(false);
2921 r.limbs[0] = 1;
2922 }
29052923 return;
29062924 }
29072925
lib/std/math/big/int_test.zig+33-30
......@@ -516,8 +516,8 @@ test "big.int add multi-single" {
516516}
517517
518518test "big.int add multi-multi" {
519 const op1 = 0xefefefef7f7f7f7f;
520 const op2 = 0xfefefefe9f9f9f9f;
519 var op1: u128 = 0xefefefef7f7f7f7f;
520 var op2: u128 = 0xfefefefe9f9f9f9f;
521521 var a = try Managed.initSet(testing.allocator, op1);
522522 defer a.deinit();
523523 var b = try Managed.initSet(testing.allocator, op2);
......@@ -830,8 +830,8 @@ test "big.int sub multi-single" {
830830}
831831
832832test "big.int sub multi-multi" {
833 const op1 = 0xefefefefefefefefefefefef;
834 const op2 = 0xabababababababababababab;
833 var op1: u128 = 0xefefefefefefefefefefefef;
834 var op2: u128 = 0xabababababababababababab;
835835
836836 var a = try Managed.initSet(testing.allocator, op1);
837837 defer a.deinit();
......@@ -914,8 +914,8 @@ test "big.int mul multi-single" {
914914}
915915
916916test "big.int mul multi-multi" {
917 const op1 = 0x998888efefefefefefefef;
918 const op2 = 0x333000abababababababab;
917 var op1: u256 = 0x998888efefefefefefefef;
918 var op2: u256 = 0x333000abababababababab;
919919 var a = try Managed.initSet(testing.allocator, op1);
920920 defer a.deinit();
921921 var b = try Managed.initSet(testing.allocator, op2);
......@@ -1033,8 +1033,8 @@ test "big.int mulWrap single-single signed" {
10331033}
10341034
10351035test "big.int mulWrap multi-multi unsigned" {
1036 const op1 = 0x998888efefefefefefefef;
1037 const op2 = 0x333000abababababababab;
1036 var op1: u256 = 0x998888efefefefefefefef;
1037 var op2: u256 = 0x333000abababababababab;
10381038 var a = try Managed.initSet(testing.allocator, op1);
10391039 defer a.deinit();
10401040 var b = try Managed.initSet(testing.allocator, op2);
......@@ -1044,7 +1044,7 @@ test "big.int mulWrap multi-multi unsigned" {
10441044 defer c.deinit();
10451045 try c.mulWrap(&a, &b, .unsigned, 65);
10461046
1047 try testing.expect((try c.to(u128)) == (op1 * op2) & ((1 << 65) - 1));
1047 try testing.expect((try c.to(u256)) == (op1 * op2) & ((1 << 65) - 1));
10481048}
10491049
10501050test "big.int mulWrap multi-multi signed" {
......@@ -1150,8 +1150,8 @@ test "big.int div single-single with rem" {
11501150}
11511151
11521152test "big.int div multi-single no rem" {
1153 const op1 = 0xffffeeeeddddcccc;
1154 const op2 = 34;
1153 var op1: u128 = 0xffffeeeeddddcccc;
1154 var op2: u128 = 34;
11551155
11561156 var a = try Managed.initSet(testing.allocator, op1);
11571157 defer a.deinit();
......@@ -1169,8 +1169,8 @@ test "big.int div multi-single no rem" {
11691169}
11701170
11711171test "big.int div multi-single with rem" {
1172 const op1 = 0xffffeeeeddddcccf;
1173 const op2 = 34;
1172 var op1: u128 = 0xffffeeeeddddcccf;
1173 var op2: u128 = 34;
11741174
11751175 var a = try Managed.initSet(testing.allocator, op1);
11761176 defer a.deinit();
......@@ -1188,8 +1188,8 @@ test "big.int div multi-single with rem" {
11881188}
11891189
11901190test "big.int div multi>2-single" {
1191 const op1 = 0xfefefefefefefefefefefefefefefefe;
1192 const op2 = 0xefab8;
1191 var op1: u128 = 0xfefefefefefefefefefefefefefefefe;
1192 var op2: u128 = 0xefab8;
11931193
11941194 var a = try Managed.initSet(testing.allocator, op1);
11951195 defer a.deinit();
......@@ -1981,22 +1981,22 @@ test "big.int shift-right negative" {
19811981 var arg = try Managed.initSet(testing.allocator, -20);
19821982 defer arg.deinit();
19831983 try a.shiftRight(&arg, 2);
1984 try testing.expect((try a.to(i32)) == -20 >> 2);
1984 try testing.expect((try a.to(i32)) == -5); // -20 >> 2 == -5
19851985
19861986 var arg2 = try Managed.initSet(testing.allocator, -5);
19871987 defer arg2.deinit();
19881988 try a.shiftRight(&arg2, 10);
1989 try testing.expect((try a.to(i32)) == -5 >> 10);
1989 try testing.expect((try a.to(i32)) == -1); // -5 >> 10 == -1
19901990}
19911991
1992test "big.int shift-left negative" {
1992test "big.int shift-right negative" {
19931993 var a = try Managed.init(testing.allocator);
19941994 defer a.deinit();
19951995
19961996 var arg = try Managed.initSet(testing.allocator, -10);
19971997 defer arg.deinit();
19981998 try a.shiftRight(&arg, 1232);
1999 try testing.expect((try a.to(i32)) == -10 >> 1232);
1999 try testing.expect((try a.to(i32)) == -1); // -10 >> 1232 == -1
20002000}
20012001
20022002test "big.int sat shift-left simple unsigned" {
......@@ -2064,34 +2064,35 @@ test "big.int sat shift-left signed simple positive" {
20642064}
20652065
20662066test "big.int sat shift-left signed multi positive" {
2067 const x = 1;
2067 var x: SignedDoubleLimb = 1;
20682068 const shift = @bitSizeOf(SignedDoubleLimb) - 1;
20692069
20702070 var a = try Managed.initSet(testing.allocator, x);
20712071 defer a.deinit();
20722072 try a.shiftLeftSat(&a, shift, .signed, @bitSizeOf(SignedDoubleLimb));
20732073
2074 try testing.expect((try a.to(SignedDoubleLimb)) == @as(SignedDoubleLimb, x) <<| shift);
2074 try testing.expect((try a.to(SignedDoubleLimb)) == x <<| shift);
20752075}
20762076
20772077test "big.int sat shift-left signed multi negative" {
2078 const x = -1;
2078 var x: SignedDoubleLimb = -1;
20792079 const shift = @bitSizeOf(SignedDoubleLimb) - 1;
20802080
20812081 var a = try Managed.initSet(testing.allocator, x);
20822082 defer a.deinit();
20832083 try a.shiftLeftSat(&a, shift, .signed, @bitSizeOf(SignedDoubleLimb));
20842084
2085 try testing.expect((try a.to(SignedDoubleLimb)) == @as(SignedDoubleLimb, x) <<| shift);
2085 try testing.expect((try a.to(SignedDoubleLimb)) == x <<| shift);
20862086}
20872087
20882088test "big.int bitNotWrap unsigned simple" {
2089 var a = try Managed.initSet(testing.allocator, 123);
2089 var x: u10 = 123;
2090 var a = try Managed.initSet(testing.allocator, x);
20902091 defer a.deinit();
20912092
20922093 try a.bitNotWrap(&a, .unsigned, 10);
20932094
2094 try testing.expect((try a.to(u10)) == ~@as(u10, 123));
2095 try testing.expect((try a.to(u10)) == ~x);
20952096}
20962097
20972098test "big.int bitNotWrap unsigned multi" {
......@@ -2104,12 +2105,13 @@ test "big.int bitNotWrap unsigned multi" {
21042105}
21052106
21062107test "big.int bitNotWrap signed simple" {
2108 var x: i11 = -456;
21072109 var a = try Managed.initSet(testing.allocator, -456);
21082110 defer a.deinit();
21092111
21102112 try a.bitNotWrap(&a, .signed, 11);
21112113
2112 try testing.expect((try a.to(i11)) == ~@as(i11, -456));
2114 try testing.expect((try a.to(i11)) == ~x);
21132115}
21142116
21152117test "big.int bitNotWrap signed multi" {
......@@ -2232,14 +2234,16 @@ test "big.int bitwise xor simple" {
22322234}
22332235
22342236test "big.int bitwise xor multi-limb" {
2235 var a = try Managed.initSet(testing.allocator, maxInt(Limb) + 1);
2237 var x: DoubleLimb = maxInt(Limb) + 1;
2238 var y: DoubleLimb = maxInt(Limb);
2239 var a = try Managed.initSet(testing.allocator, x);
22362240 defer a.deinit();
2237 var b = try Managed.initSet(testing.allocator, maxInt(Limb));
2241 var b = try Managed.initSet(testing.allocator, y);
22382242 defer b.deinit();
22392243
22402244 try a.bitXor(&a, &b);
22412245
2242 try testing.expect((try a.to(DoubleLimb)) == (maxInt(Limb) + 1) ^ maxInt(Limb));
2246 try testing.expect((try a.to(DoubleLimb)) == x ^ y);
22432247}
22442248
22452249test "big.int bitwise xor single negative simple" {
......@@ -2327,7 +2331,6 @@ test "big.int bitwise or multi-limb" {
23272331
23282332 try a.bitOr(&a, &b);
23292333
2330 // TODO: big.int.cpp or is wrong on multi-limb.
23312334 try testing.expect((try a.to(DoubleLimb)) == (maxInt(Limb) + 1) + maxInt(Limb));
23322335}
23332336
src/value.zig+6-2
......@@ -4180,8 +4180,12 @@ pub const Value = extern union {
41804180 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));
41814181 if (result_limbs == 0) {
41824182 // The shift is enough to remove all the bits from the number, which means the
4183 // result is zero.
4184 return Value.zero;
4183 // result is 0 or -1 depending on the sign.
4184 if (lhs_bigint.positive) {
4185 return Value.zero;
4186 } else {
4187 return Value.negative_one;
4188 }
41854189 }
41864190
41874191 const limbs = try allocator.alloc(
test/behavior.zig+1
......@@ -115,6 +115,7 @@ test {
115115 _ = @import("behavior/bugs/13164.zig");
116116 _ = @import("behavior/bugs/13159.zig");
117117 _ = @import("behavior/bugs/13171.zig");
118 _ = @import("behavior/bugs/13209.zig");
118119 _ = @import("behavior/bugs/13285.zig");
119120 _ = @import("behavior/bugs/13435.zig");
120121 _ = @import("behavior/byteswap.zig");
test/behavior/bugs/13209.zig created+5
......@@ -0,0 +1,5 @@
1const std = @import("std");
2test {
3 try std.testing.expect(-1 == @as(i8, -3) >> 2);
4 try std.testing.expect(-1 == -3 >> 2000);
5}