aboutsummaryrefslogtreecommitdiffstats
path: root/libj2_j2i_add_j2i.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libj2_j2i_add_j2i.c207
1 files changed, 206 insertions, 1 deletions
diff --git a/libj2_j2i_add_j2i.c b/libj2_j2i_add_j2i.c
index 2d0acf5..f1b015b 100644
--- a/libj2_j2i_add_j2i.c
+++ b/libj2_j2i_add_j2i.c
@@ -23,12 +23,16 @@ static void
check_(uintmax_t a_high, uintmax_t a_low, uintmax_t b_high, uintmax_t b_low,
uintmax_t r_high, uintmax_t r_low, int r_overflow)
{
- struct libj2_j2i a, b, r, a_saved, b_saved, expected;
+ struct libj2_j2i a, b, r, a_saved, b_saved, expected, expected_plus_one, expected_minus_one;
+ int carry;
a_saved = (struct libj2_j2i){.high = a_high, .low = a_low};
b_saved = (struct libj2_j2i){.high = b_high, .low = b_low};
expected = (struct libj2_j2i){.high = r_high, .low = r_low};
+ libj2_j2i_add_ji_to_j2i(&expected, +1, &expected_plus_one);
+ libj2_j2i_add_ji_to_j2i(&expected, -1, &expected_minus_one);
+
a = a_saved;
b = b_saved;
libj2_j2i_add_j2i(&a, &b);
@@ -116,6 +120,108 @@ check_(uintmax_t a_high, uintmax_t a_low, uintmax_t b_high, uintmax_t b_low,
EXPECT(r_overflow > 0 ? libj2_j2i_is_max(&b) :
r_overflow ? libj2_j2i_is_min(&b) : libj2_j2i_eq_j2i(&b, &expected));
EXPECT(libj2_j2i_eq_j2i(&a, &a_saved));
+
+ carry = 0;
+ a = a_saved;
+ b = b_saved;
+ libj2_j2i_add_j2i_carry(&a, &b, &carry);
+ EXPECT(carry == r_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&a, &expected));
+ EXPECT(libj2_j2i_eq_j2i(&b, &b_saved));
+
+ carry = 0;
+ r = (struct libj2_j2i){111, 222};
+ a = a_saved;
+ b = b_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &b, &r, &carry);
+ EXPECT(carry == r_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&r, &expected));
+ EXPECT(libj2_j2i_eq_j2i(&a, &a_saved));
+ EXPECT(libj2_j2i_eq_j2i(&b, &b_saved));
+
+ carry = 0;
+ a = a_saved;
+ b = b_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &b, &a, &carry);
+ EXPECT(carry == r_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&a, &expected));
+ EXPECT(libj2_j2i_eq_j2i(&b, &b_saved));
+
+ carry = 0;
+ a = a_saved;
+ b = b_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &b, &b, &carry);
+ EXPECT(carry == r_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&b, &expected));
+ EXPECT(libj2_j2i_eq_j2i(&a, &a_saved));
+
+ carry = +1;
+ a = a_saved;
+ b = b_saved;
+ libj2_j2i_add_j2i_carry(&a, &b, &carry);
+ EXPECT(carry >= r_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&a, &expected_plus_one));
+ EXPECT(libj2_j2i_eq_j2i(&b, &b_saved));
+
+ carry = +1;
+ r = (struct libj2_j2i){111, 222};
+ a = a_saved;
+ b = b_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &b, &r, &carry);
+ EXPECT(carry >= r_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&r, &expected_plus_one));
+ EXPECT(libj2_j2i_eq_j2i(&a, &a_saved));
+ EXPECT(libj2_j2i_eq_j2i(&b, &b_saved));
+
+ carry = +1;
+ a = a_saved;
+ b = b_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &b, &a, &carry);
+ EXPECT(carry >= r_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&a, &expected_plus_one));
+ EXPECT(libj2_j2i_eq_j2i(&b, &b_saved));
+
+ carry = +1;
+ a = a_saved;
+ b = b_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &b, &b, &carry);
+ EXPECT(carry >= r_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&b, &expected_plus_one));
+ EXPECT(libj2_j2i_eq_j2i(&a, &a_saved));
+
+ carry = -1;
+ a = a_saved;
+ b = b_saved;
+ libj2_j2i_add_j2i_carry(&a, &b, &carry);
+ EXPECT(carry <= r_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&a, &expected_minus_one));
+ EXPECT(libj2_j2i_eq_j2i(&b, &b_saved));
+
+ carry = -1;
+ r = (struct libj2_j2i){111, 222};
+ a = a_saved;
+ b = b_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &b, &r, &carry);
+ EXPECT(carry <= r_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&r, &expected_minus_one));
+ EXPECT(libj2_j2i_eq_j2i(&a, &a_saved));
+ EXPECT(libj2_j2i_eq_j2i(&b, &b_saved));
+
+ carry = -1;
+ a = a_saved;
+ b = b_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &b, &a, &carry);
+ EXPECT(carry <= r_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&a, &expected_minus_one));
+ EXPECT(libj2_j2i_eq_j2i(&b, &b_saved));
+
+ carry = -1;
+ a = a_saved;
+ b = b_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &b, &b, &carry);
+ EXPECT(carry <= r_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&b, &expected_minus_one));
+ EXPECT(libj2_j2i_eq_j2i(&a, &a_saved));
}
@@ -177,6 +283,8 @@ check_double(uintmax_t high, uintmax_t low)
uintmax_t expected_high = (high << 1 | low >> (LIBJ2_JU_BIT - 1U));
uintmax_t expected_low = low << 1;
int expected_overflow = (int)(high >> (LIBJ2_JU_BIT - 2U));
+ struct libj2_j2i expected_plus_one, expected_minus_one;
+ int carry;
expected_overflow ^= expected_overflow >> 1;
expected_overflow &= 1;
@@ -187,6 +295,9 @@ check_double(uintmax_t high, uintmax_t low)
a_saved = (struct libj2_j2i){.high = high, .low = low};
expected = (struct libj2_j2i){.high = expected_high, .low = expected_low};
+ libj2_j2i_add_ji_to_j2i(&expected, +1, &expected_plus_one);
+ libj2_j2i_add_ji_to_j2i(&expected, -1, &expected_minus_one);
+
a = a_saved;
b = a_saved;
libj2_j2i_add_j2i(&a, &b);
@@ -240,6 +351,66 @@ check_double(uintmax_t high, uintmax_t low)
libj2_j2i_sat_add_j2i_to_j2i(&a, &a, &a);
EXPECT(expected_overflow > 0 ? libj2_j2i_is_max(&a) :
expected_overflow ? libj2_j2i_is_min(&a) : libj2_j2i_eq_j2i(&a, &expected));
+
+ carry = 0;
+ a = a_saved;
+ libj2_j2i_add_j2i_carry(&a, &a, &carry);
+ EXPECT(carry == expected_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&a, &expected));
+
+ carry = 0;
+ r = (struct libj2_j2i){111, 222};
+ a = a_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &a, &r, &carry);
+ EXPECT(carry == expected_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&r, &expected));
+ EXPECT(libj2_j2i_eq_j2i(&a, &a_saved));
+
+ carry = 0;
+ a = a_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &a, &a, &carry);
+ EXPECT(carry == expected_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&a, &expected));
+
+ carry = +1;
+ a = a_saved;
+ libj2_j2i_add_j2i_carry(&a, &a, &carry);
+ EXPECT(carry >= expected_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&a, &expected_plus_one));
+
+ carry = +1;
+ r = (struct libj2_j2i){111, 222};
+ a = a_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &a, &r, &carry);
+ EXPECT(carry >= expected_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&r, &expected_plus_one));
+ EXPECT(libj2_j2i_eq_j2i(&a, &a_saved));
+
+ carry = +1;
+ a = a_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &a, &a, &carry);
+ EXPECT(carry >= expected_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&a, &expected_plus_one));
+
+ carry = -1;
+ a = a_saved;
+ libj2_j2i_add_j2i_carry(&a, &a, &carry);
+ EXPECT(carry <= expected_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&a, &expected_minus_one));
+
+ carry = -1;
+ r = (struct libj2_j2i){111, 222};
+ a = a_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &a, &r, &carry);
+ EXPECT(carry <= expected_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&r, &expected_minus_one));
+ EXPECT(libj2_j2i_eq_j2i(&a, &a_saved));
+
+ carry = -1;
+ a = a_saved;
+ libj2_j2i_add_j2i_to_j2i_carry(&a, &a, &a, &carry);
+ EXPECT(carry <= expected_overflow);
+ EXPECT(libj2_j2i_eq_j2i(&a, &expected_minus_one));
}
@@ -248,6 +419,8 @@ main(void)
{
uintmax_t a, b, c, d, max, min, umax, vs[12];
unsigned i, ii, ij, jj, k;
+ struct libj2_j2i u, v;
+ int carry;
srand((unsigned)time(NULL));
@@ -333,6 +506,38 @@ main(void)
}
}
+ carry = +1;
+ libj2_j2i_max(&u);
+ libj2_j2i_zero(&v);
+ libj2_j2i_add_j2i_to_j2i_carry(&u, &v, &u, &carry);
+ EXPECT(carry == +1);
+ EXPECT(libj2_j2i_is_min(&u));
+ EXPECT(libj2_j2i_is_zero(&v));
+
+ carry = +1;
+ libj2_j2i_max(&u);
+ libj2_j2i_zero(&v);
+ libj2_j2i_add_j2i_carry(&u, &v, &carry);
+ EXPECT(carry == +1);
+ EXPECT(libj2_j2i_is_min(&u));
+ EXPECT(libj2_j2i_is_zero(&v));
+
+ carry = -1;
+ libj2_j2i_min(&u);
+ libj2_j2i_zero(&v);
+ libj2_j2i_add_j2i_to_j2i_carry(&u, &v, &u, &carry);
+ EXPECT(carry == -1);
+ EXPECT(libj2_j2i_is_max(&u));
+ EXPECT(libj2_j2i_is_zero(&v));
+
+ carry = -1;
+ libj2_j2i_min(&u);
+ libj2_j2i_zero(&v);
+ libj2_j2i_add_j2i_carry(&u, &v, &carry);
+ EXPECT(carry == -1);
+ EXPECT(libj2_j2i_is_max(&u));
+ EXPECT(libj2_j2i_is_zero(&v));
+
return 0;
}