zig

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

suboti4_test.zig (2563B) - Raw


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