zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

subosi4_test.zig (2457B) - Raw


      1 const subo = @import("subo.zig");
      2 const testing = @import("std").testing;
      3 
      4 fn test__subosi4(a: i32, b: i32) !void {
      5     var result_ov: c_int = undefined;
      6     var expected_ov: c_int = undefined;
      7     const result = subo.__subosi4(a, b, &result_ov);
      8     const expected: i32 = simple_subosi4(a, b, &expected_ov);
      9     try testing.expectEqual(expected, result);
     10     try testing.expectEqual(expected_ov, result_ov);
     11 }
     12 
     13 // 2 cases on evaluating `a-b`:
     14 // 1. `a-b` may underflow, iff b>0 && a<0 and a-b < min <=> a<min+b
     15 // 2. `a-b` may overflow,  iff b<0 && a>0 and a-b > max <=> a>max+b
     16 // `-b` evaluation may overflow, iff b==min, but this is handled by the hardware
     17 pub fn simple_subosi4(a: i32, b: i32, overflow: *c_int) i32 {
     18     overflow.* = 0;
     19     const min: i32 = -2147483648;
     20     const max: i32 = 2147483647;
     21     if (((b > 0) and (a < min + b)) or
     22         ((b < 0) and (a > max + b)))
     23         overflow.* = 1;
     24     return a -% b;
     25 }
     26 
     27 test "subosi3" {
     28     // -2^31 <= i32 <= 2^31-1
     29     // 2^31 = 2147483648
     30     // 2^31-1 = 2147483647
     31     const min: i32 = -2147483648;
     32     const max: i32 = 2147483647;
     33     var i: i32 = 1;
     34     while (i < max) : (i *|= 2) {
     35         try test__subosi4(i, i);
     36         try test__subosi4(-i, -i);
     37         try test__subosi4(i, -i);
     38         try test__subosi4(-i, i);
     39     }
     40 
     41     // edge cases
     42     // 0 - 0       = 0
     43     // MIN - MIN   = 0
     44     // MAX - MAX   = 0
     45     // 0   - MIN     overflow
     46     // 0   - MAX   = MIN+1
     47     // MIN - 0     = MIN
     48     // MAX - 0     = MAX
     49     // MIN - MAX     overflow
     50     // MAX - MIN     overflow
     51     try test__subosi4(0, 0);
     52     try test__subosi4(min, min);
     53     try test__subosi4(max, max);
     54     try test__subosi4(0, min);
     55     try test__subosi4(0, max);
     56     try test__subosi4(min, 0);
     57     try test__subosi4(max, 0);
     58     try test__subosi4(min, max);
     59     try test__subosi4(max, min);
     60 
     61     // derived edge cases
     62     // MIN+1 - MIN = 1
     63     // MAX-1 - MAX = -1
     64     // 1     - MIN   overflow
     65     // -1    - MIN = MAX
     66     // -1    - MAX = MIN
     67     // +1    - MAX = MIN+2
     68     // MIN   - 1     overflow
     69     // MIN   - -1  = MIN+1
     70     // MAX   - 1   = MAX-1
     71     // MAX   - -1    overflow
     72     try test__subosi4(min + 1, min);
     73     try test__subosi4(max - 1, max);
     74     try test__subosi4(1, min);
     75     try test__subosi4(-1, min);
     76     try test__subosi4(-1, max);
     77     try test__subosi4(1, max);
     78     try test__subosi4(min, 1);
     79     try test__subosi4(min, -1);
     80     try test__subosi4(max, -1);
     81     try test__subosi4(max, 1);
     82 }