aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Makefile17
-rw-r--r--libj2.h2
-rw-r--r--libj2/saturated-math.h451
-rw-r--r--libj2_j2i_sat_add_j2i.c19
l---------libj2_j2i_sat_add_j2i_to_j2i.31
-rw-r--r--libj2_j2i_sat_add_j2i_to_j2i.c12
l---------libj2_j2i_sat_add_ji.31
-rw-r--r--libj2_j2i_sat_add_ji.c12
l---------libj2_j2i_sat_add_ji_to_j2i.31
-rw-r--r--libj2_j2i_sat_add_ji_to_j2i.c12
-rw-r--r--libj2_j2i_sat_lsh.c17
l---------libj2_j2i_sat_lsh_to_j2i.31
-rw-r--r--libj2_j2i_sat_lsh_to_j2i.c12
l---------libj2_j2i_sat_rsub_j2i.31
-rw-r--r--libj2_j2i_sat_rsub_j2i.c12
l---------libj2_j2i_sat_rsub_ji.31
-rw-r--r--libj2_j2i_sat_rsub_ji.c12
-rw-r--r--libj2_j2i_sat_sub_j2i.c21
l---------libj2_j2i_sat_sub_j2i_to_j2i.31
-rw-r--r--libj2_j2i_sat_sub_j2i_to_j2i.c12
l---------libj2_j2i_sat_sub_ji.31
-rw-r--r--libj2_j2i_sat_sub_ji.c12
l---------libj2_j2i_sat_sub_ji_to_j2i.31
-rw-r--r--libj2_j2i_sat_sub_ji_to_j2i.c12
l---------libj2_ji_sat_add_j2i_to_j2i.31
-rw-r--r--libj2_ji_sat_add_j2i_to_j2i.c12
l---------libj2_ji_sat_lsh_to_j2i.31
-rw-r--r--libj2_ji_sat_lsh_to_j2i.c12
l---------libj2_ji_sat_sub_j2i_to_j2i.31
-rw-r--r--libj2_ji_sat_sub_j2i_to_j2i.c12
30 files changed, 679 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index 9cef96d..d81787a 100644
--- a/Makefile
+++ b/Makefile
@@ -506,7 +506,22 @@ OBJ =\
libj2_j2i_rdiv_j2i_underflow.o\
libj2_j2i_rdivmod_j2i.o\
libj2_j2i_rdivmod_j2i_to_j2i.o\
- libj2_j2i_rmod_j2i.o
+ libj2_j2i_rmod_j2i.o\
+ libj2_j2i_sat_lsh.o\
+ libj2_j2i_sat_lsh_to_j2i.o\
+ libj2_ji_sat_lsh_to_j2i.o\
+ libj2_j2i_sat_add_ji.o\
+ libj2_j2i_sat_add_ji_to_j2i.o\
+ libj2_ji_sat_add_j2i_to_j2i.o\
+ libj2_j2i_sat_add_j2i.o\
+ libj2_j2i_sat_add_j2i_to_j2i.o\
+ libj2_j2i_sat_sub_ji.o\
+ libj2_j2i_sat_sub_ji_to_j2i.o\
+ libj2_j2i_sat_sub_j2i.o\
+ libj2_j2i_sat_sub_j2i_to_j2i.o\
+ libj2_ji_sat_sub_j2i_to_j2i.o\
+ libj2_j2i_sat_rsub_j2i.o\
+ libj2_j2i_sat_rsub_ji.o
SUBHDR =\
libj2/constants.h\
diff --git a/libj2.h b/libj2.h
index 7eb90d7..1648c5e 100644
--- a/libj2.h
+++ b/libj2.h
@@ -166,7 +166,7 @@ enum libj2_overflow {
#include "libj2/subtraction.h"
#include "libj2/multiplication.h"
#include "libj2/division.h"
-#include "libj2/saturated-math.h" /* TODO add signed versions */
+#include "libj2/saturated-math.h" /* TODO add signed versions (mul) */
#include "libj2/strings.h"
diff --git a/libj2/saturated-math.h b/libj2/saturated-math.h
index 9812e9b..0e5627f 100644
--- a/libj2/saturated-math.h
+++ b/libj2/saturated-math.h
@@ -93,6 +93,108 @@ libj2_ju_sat_lsh_to_j2u(uintmax_t a, unsigned b, struct libj2_j2u *res)
}
+/**
+ * Shift the bits in a signed double-max precision
+ * integer to more signficant positions (left-shift)
+ *
+ * If any set bit is shifted out of precision, it will
+ * be regarded an arithmetic overflow, and the result
+ * will be saturated to the maximum value (if positive)
+ * or minimum value (if negaitve) that can be
+ * represented
+ *
+ * `libj2_j2i_sat_lsh` is a version `libj2_j2i_lsh`
+ * that uses saturated arithmetics
+ *
+ * This is equivalent to multiplying `a` by the `b`th
+ * power of 2, using satured multiplication
+ *
+ * @param a The integer to shift, also used as the
+ * output parameter for the result
+ * @param b The number of positions to shift each bit
+ *
+ * @since 1.1
+ */
+inline void
+libj2_j2i_sat_lsh(struct libj2_j2i *a, unsigned b)
+{
+ int r = libj2_j2i_lsh_overflow(a, b);
+ if (r > 0)
+ libj2_j2i_max(a);
+ else if (r)
+ libj2_j2i_min(a);
+}
+
+
+/**
+ * Shift the bits in a signed double-max precision
+ * integer to more signficant positions (left-shift)
+ *
+ * If any set bit is shifted out of precision, it will
+ * be regarded an arithmetic overflow, and the result
+ * will be saturated to the maximum value (if positive)
+ * or minimum value (if negaitve) that can be
+ * represented
+ *
+ * `libj2_j2i_sat_lsh_to_j2i` is a version
+ * `libj2_j2i_lsh_to_j2i` that uses saturated arithmetics
+ *
+ * This is equivalent to multiplying `a` by the `b`th
+ * power of 2, using satured multiplication
+ *
+ * @param a The integer to shift
+ * @param b The number of positions to shift each bit
+ * @param res Output parameter for the result
+ *
+ * @since 1.1
+ */
+inline void
+libj2_j2i_sat_lsh_to_j2i(const struct libj2_j2i *a, unsigned b, struct libj2_j2i *res)
+{
+ int r = libj2_j2i_lsh_to_j2i_overflow(a, b, res);
+ if (r > 0)
+ libj2_j2i_max(res);
+ else if (r)
+ libj2_j2i_min(res);
+}
+
+
+/**
+ * Shift the bits in a signed double-max precision
+ * integer, represented by a signed max precision
+ * integer and whose high part, of the value bits,
+ * is treated as having the value 0, to more
+ * signficant positions (left-shift)
+ *
+ * If any set bit is shifted out of precision, it will
+ * be regarded an arithmetic overflow, and the result
+ * will be saturated to the maximum value (if positive)
+ * or minimum value (if negaitve) that can be
+ * represented
+ *
+ * `libj2_ji_sat_lsh_to_j2i` is a version
+ * `libj2_ji_lsh_to_j2i` that uses saturated arithmetics
+ *
+ * This is equivalent to multiplying `a` by the `b`th
+ * power of 2, using satured multiplication
+ *
+ * @param a The integer to shift
+ * @param b The number of positions to shift each bit
+ * @param res Output parameter for the result
+ *
+ * @since 1.1
+ */
+inline void
+libj2_ji_sat_lsh_to_j2i(intmax_t a, unsigned b, struct libj2_j2i *res)
+{
+ int r = libj2_ji_lsh_to_j2i_overflow(a, b, res);
+ if (r > 0)
+ libj2_j2i_max(res);
+ else if (r)
+ libj2_j2i_min(res);
+}
+
+
@@ -214,6 +316,144 @@ libj2_j2u_sat_add_j2u_to_j2u(const struct libj2_j2u *a, const struct libj2_j2u *
}
+/**
+ * Calculate the saturated sum of a signed double-max
+ * precision integer and a signed max precision integer
+ *
+ * `libj2_j2i_sat_add_ji` is a version
+ * `libj2_j2i_add_ji` that uses saturated arithmetics,
+ * meaning that if the result is too large to be
+ * represented it is saturated into the maximum value
+ * (if positive) or minimum value (if negative) that
+ * can be represented
+ *
+ * @param a The augend, and output parameter for the sum
+ * @param b The addend
+ *
+ * @since 1.1
+ */
+inline void
+libj2_j2i_sat_add_ji(struct libj2_j2i *a, intmax_t b)
+{
+ int r = libj2_j2i_add_ji_overflow(a, b);
+ if (r > 0)
+ libj2_j2i_max(a);
+ else if (r)
+ libj2_j2i_min(a);
+}
+
+
+/**
+ * Calculate the saturated sum of a signed double-max
+ * precision integer and a signed max precision integer
+ *
+ * `libj2_j2i_sat_add_ji_to_j2i` is a version
+ * `libj2_j2i_add_ji_to_j2i` that uses saturated
+ * arithmetics, meaning that if the result is too
+ * large to be represented it is saturated into
+ * the maximum value (if positive) or minimum value
+ * (if negative) that can be represented
+ *
+ * @param a The augend
+ * @param b The addend
+ * @param res Output parameter for the sum
+ *
+ * @since 1.1
+ */
+inline void
+libj2_j2i_sat_add_ji_to_j2i(const struct libj2_j2i *a, intmax_t b, struct libj2_j2i *res)
+{
+ int r = libj2_j2i_add_ji_to_j2i_overflow(a, b, res);
+ if (r > 0)
+ libj2_j2i_max(res);
+ else if (r)
+ libj2_j2i_min(res);
+}
+
+
+/**
+ * Calculate the saturated sum of a signed max precision
+ * integer and a signed double-max precision integer
+ *
+ * `libj2_ji_sat_add_j2i_to_j2i` is a version
+ * `libj2_ji_add_j2i_to_j2i` that uses saturated
+ * arithmetics, meaning that if the result is too
+ * large to be represented it is saturated into
+ * the maximum value (if positive) or minimum
+ * value (if negative) that can be represented
+ *
+ * @param a The augend
+ * @param b The addend
+ * @param res Output parameter for the sum
+ *
+ * @since 1.1
+ */
+inline void
+libj2_ji_sat_add_j2i_to_j2i(intmax_t a, const struct libj2_j2i *b, struct libj2_j2i *res)
+{
+ int r = libj2_ji_add_j2i_to_j2i_overflow(a, b, res);
+ if (r > 0)
+ libj2_j2i_max(res);
+ else if (r)
+ libj2_j2i_min(res);
+}
+
+
+/**
+ * Calculate the saturated sum of two signed double-max
+ * precision integers
+ *
+ * `libj2_j2i_sat_add_j2i` is a version
+ * `libj2_j2i_add_j2i` that uses saturated arithmetics,
+ * meaning that if the result is too large to be
+ * represented it is saturated into the maximum value
+ * (if positive) or minimum value (if negative) that
+ * can be represented
+ *
+ * @param a The augend, and output parameter for the sum
+ * @param b The addend
+ *
+ * @since 1.1
+ */
+inline void
+libj2_j2i_sat_add_j2i(struct libj2_j2i *a, const struct libj2_j2i *b)
+{
+ int r = libj2_j2i_add_j2i_overflow(a, b);
+ if (r > 0)
+ libj2_j2i_max(a);
+ else if (r)
+ libj2_j2i_min(a);
+}
+
+
+/**
+ * Calculate the saturated sum of two signed double-max
+ * precision integers
+ *
+ * `libj2_j2i_sat_add_j2i_to_j2i` is a version
+ * `libj2_j2i_add_j2i_to_j2i` that uses saturated
+ * arithmetics, meaning that if the result is too
+ * large to be represented it is saturated into
+ * the maximum value (if positive) or minimum
+ * value (if negative) that can be represented
+ *
+ * @param a The augend
+ * @param b The addend
+ * @param res Output parameter for the sum
+ *
+ * @since 1.1
+ */
+inline void
+libj2_j2i_sat_add_j2i_to_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b, struct libj2_j2i *res)
+{
+ int r = libj2_j2i_add_j2i_to_j2i_overflow(a, b, res);
+ if (r > 0)
+ libj2_j2i_max(res);
+ else if (r)
+ libj2_j2i_min(res);
+}
+
+
@@ -368,7 +608,7 @@ libj2_ju_sat_sub_j2u_to_j2u(uintmax_t a, const struct libj2_j2u *b, struct libj2
/**
* Calculate the saturated difference between two
* unsigned max precision integers; in this variant
- * of `libj2_j2u_sub_j2u`, the minuend (left-hand)
+ * of `libj2_j2u_sat_sub_j2u`, the minuend (left-hand)
* is the second parameter and the subtrahend
* (right-hand) is the first parameter
*
@@ -396,7 +636,7 @@ libj2_j2u_sat_rsub_j2u(struct libj2_j2u *a, const struct libj2_j2u *b)
* Calculate the saturated difference between an
* unsigned max precision integer (minuend) and an
* unsigned double-max precision integer (subtrahend);
- * in this variant of `libj2_j2u_sub_ju`, the
+ * in this variant of `libj2_j2u_sat_sub_ju`, the
* minuend (left-hand) is the second parameter
* and the subtrahend (right-hand) is the first
* parameter
@@ -421,6 +661,213 @@ libj2_j2u_sat_rsub_ju(struct libj2_j2u *a, uintmax_t b)
}
+/**
+ * Calculate the saturated difference between n
+ * signed double-max precision integer (minuend)
+ * and a signed max precision integer (subtrahend)
+ *
+ * `libj2_j2i_sat_sub_ji` is a version
+ * `libj2_j2i_sub_ji` that uses saturated
+ * arithmetics, meaning that if the result is too
+ * large to be represented it is saturated into
+ * the maximum value (if positive) or minimum value
+ * (if negative) that can be represented
+ *
+ * @param a The minuend (left-hand), also used as the
+ * output parameter for the difference
+ * @param b The subtrahend (right-hand)
+ *
+ * @since 1.1
+ */
+inline void
+libj2_j2i_sat_sub_ji(struct libj2_j2i *a, intmax_t b)
+{
+ int r = libj2_j2i_sub_ji_overflow(a, b);
+ if (r > 0)
+ libj2_j2i_max(a);
+ else if (r)
+ libj2_j2i_min(a);
+}
+
+
+/**
+ * Calculate the saturated difference between a
+ * signed double-max precision integer (minuend)
+ * and a signed max precision integer (subtrahend)
+ *
+ * `libj2_j2i_sat_sub_ji_to_j2i` is a version
+ * `libj2_j2i_sub_ji_to_j2i` that uses saturated
+ * arithmetics, meaning that if the result is too
+ * large to be represented it is saturated into
+ * the maximum value (if positive) or minimum value
+ * (if negative) that can be represented
+ *
+ * @param a The minuend (left-hand)
+ * @param b The subtrahend (right-hand)
+ * @param res Output parameter for the difference
+ *
+ * @since 1.1
+ */
+inline void
+libj2_j2i_sat_sub_ji_to_j2i(const struct libj2_j2i *a, intmax_t b, struct libj2_j2i *res)
+{
+ int r = libj2_j2i_sub_ji_to_j2i_overflow(a, b, res);
+ if (r > 0)
+ libj2_j2i_max(res);
+ else if (r)
+ libj2_j2i_min(res);
+}
+
+
+/**
+ * Calculate the saturated difference between two
+ * signed double-max precision integers
+ *
+ * `libj2_j2i_sat_sub_j2i` is a version
+ * `libj2_j2i_sub_j2i` that uses saturated
+ * arithmetics, meaning that if the result is too
+ * large to be represented it is saturated into
+ * the maximum value (if positive) or minimum value
+ * (if negative) that can be represented
+ *
+ * @param a The minuend (left-hand), also used
+ * as the output parameter for the difference
+ * @param b The subtrahend (right-hand)
+ *
+ * @since 1.1
+ */
+inline void
+libj2_j2i_sat_sub_j2i(struct libj2_j2i *a, const struct libj2_j2i *b)
+{
+ int r = libj2_j2i_sub_j2i_overflow(a, b);
+ if (r > 0)
+ libj2_j2i_max(a);
+ else if (r)
+ libj2_j2i_min(a);
+}
+
+
+/**
+ * Calculate the saturated difference between two
+ * signed double-max precision integers
+ *
+ * `libj2_j2i_sat_sub_j2i_to_j2i` is a version
+ * `libj2_j2i_sub_j2i_to_j2i` that uses saturated
+ * arithmetics, meaning that if the result is too
+ * large to be represented it is saturated into
+ * the maximum value (if positive) or minimum value
+ * (if negative) that can be represented
+ *
+ * @param a The minuend (left-hand)
+ * @param b The subtrahend (right-hand)
+ * @param res Output parameter for the difference
+ *
+ * @since 1.1
+ */
+inline void
+libj2_j2i_sat_sub_j2i_to_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b, struct libj2_j2i *res)
+{
+ int r = libj2_j2i_sub_j2i_to_j2i_overflow(a, b, res);
+ if (r > 0)
+ libj2_j2i_max(res);
+ else if (r)
+ libj2_j2i_min(res);
+}
+
+
+/**
+ * Calculate the saturated difference between a
+ * signed max precision integer (minuend) and a
+ * signed double-max precision integer (subtrahend)
+ *
+ * `libj2_ji_sat_sub_j2i_to_j2i` is a version
+ * `libj2_ji_sub_j2i_to_j2i` that uses saturated
+ * arithmetics, meaning that if the result is too
+ * large to be represented it is saturated into
+ * the maximum value (if positive) or minimum value
+ * (if negative) that can be represented
+ *
+ * @param a The minuend (left-hand)
+ * @param b The subtrahend (right-hand)
+ * @param res Output parameter for the difference
+ *
+ * @since 1.1
+ */
+inline void
+libj2_ji_sat_sub_j2i_to_j2i(intmax_t a, const struct libj2_j2i *b, struct libj2_j2i *res)
+{
+ int r = libj2_ji_sub_j2i_to_j2i_overflow(a, b, res);
+ if (r > 0)
+ libj2_j2i_max(res);
+ else if (r)
+ libj2_j2i_min(res);
+}
+
+
+/**
+ * Calculate the saturated difference between two
+ * unsigned max precision integers; in this variant
+ * of `libj2_j2i_sat_sub_j2i`, the minuend (left-hand)
+ * is the second parameter and the subtrahend
+ * (right-hand) is the first parameter
+ *
+ * `libj2_j2i_sat_rsub_j2i` is a version
+ * `libj2_j2i_rsub_j2i` that uses saturated
+ * arithmetics, meaning that if the result is too
+ * large to be represented it is saturated into
+ * the maximum value (if positive) or minimum value
+ * (if negative) that can be represented
+ *
+ * @param a The subtrahend (right-hand), also used as
+ * the output parameter for the difference
+ * @param b The minuend (left-hand)
+ *
+ * @since 1.1
+ */
+inline void
+libj2_j2i_sat_rsub_j2i(struct libj2_j2i *a, const struct libj2_j2i *b)
+{
+ int r = libj2_j2i_rsub_j2i_overflow(a, b);
+ if (r > 0)
+ libj2_j2i_max(a);
+ else if (r)
+ libj2_j2i_min(a);
+}
+
+
+/**
+ * Calculate the saturated difference between an
+ * unsigned max precision integer (minuend) and an
+ * unsigned double-max precision integer (subtrahend);
+ * in this variant of `libj2_j2i_sat_sub_ji`, the
+ * minuend (left-hand) is the second parameter
+ * and the subtrahend (right-hand) is the first
+ * parameter
+ *
+ * `libj2_j2i_sat_rsub_ji` is a version
+ * `libj2_j2i_rsub_ji` that uses saturated
+ * arithmetics, meaning that if the result is too
+ * large to be represented it is saturated into
+ * the maximum value (if positive) or minimum value
+ * (if negative) that can be represented
+ *
+ * @param a The subtrahend (right-hand), also used as
+ * the output parameter for the difference
+ * @param b The minuend (left-hand)
+ *
+ * @since 1.1
+ */
+inline void
+libj2_j2i_sat_rsub_ji(struct libj2_j2i *a, intmax_t b)
+{
+ int r = libj2_j2i_rsub_ji_overflow(a, b);
+ if (r > 0)
+ libj2_j2i_max(a);
+ else if (r)
+ libj2_j2i_min(a);
+}
+
+
diff --git a/libj2_j2i_sat_add_j2i.c b/libj2_j2i_sat_add_j2i.c
new file mode 100644
index 0000000..f42f28f
--- /dev/null
+++ b/libj2_j2i_sat_add_j2i.c
@@ -0,0 +1,19 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_j2i_sat_add_j2i(struct libj2_j2i *a, const struct libj2_j2i *b);
+/* TODO Add man pages
+ * libj2_j2i_sat_add_j2i
+ * libj2_j2i_sat_add_j2i_to_j2i
+ * libj2_j2i_sat_add_ji
+ * libj2_j2i_sat_add_ji_to_j2i
+ * libj2_ji_sat_add_j2i_to_j2i
+ */
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_j2i_sat_add_j2i_to_j2i.3 b/libj2_j2i_sat_add_j2i_to_j2i.3
new file mode 120000
index 0000000..02a6a62
--- /dev/null
+++ b/libj2_j2i_sat_add_j2i_to_j2i.3
@@ -0,0 +1 @@
+libj2_j2i_sat_add_j2i.3 \ No newline at end of file
diff --git a/libj2_j2i_sat_add_j2i_to_j2i.c b/libj2_j2i_sat_add_j2i_to_j2i.c
new file mode 100644
index 0000000..4ec77fb
--- /dev/null
+++ b/libj2_j2i_sat_add_j2i_to_j2i.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_j2i_sat_add_j2i_to_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b, struct libj2_j2i *res);
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_j2i_sat_add_ji.3 b/libj2_j2i_sat_add_ji.3
new file mode 120000
index 0000000..02a6a62
--- /dev/null
+++ b/libj2_j2i_sat_add_ji.3
@@ -0,0 +1 @@
+libj2_j2i_sat_add_j2i.3 \ No newline at end of file
diff --git a/libj2_j2i_sat_add_ji.c b/libj2_j2i_sat_add_ji.c
new file mode 100644
index 0000000..4517748
--- /dev/null
+++ b/libj2_j2i_sat_add_ji.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_j2i_sat_add_ji(struct libj2_j2i *a, intmax_t b);
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_j2i_sat_add_ji_to_j2i.3 b/libj2_j2i_sat_add_ji_to_j2i.3
new file mode 120000
index 0000000..02a6a62
--- /dev/null
+++ b/libj2_j2i_sat_add_ji_to_j2i.3
@@ -0,0 +1 @@
+libj2_j2i_sat_add_j2i.3 \ No newline at end of file
diff --git a/libj2_j2i_sat_add_ji_to_j2i.c b/libj2_j2i_sat_add_ji_to_j2i.c
new file mode 100644
index 0000000..3c1580b
--- /dev/null
+++ b/libj2_j2i_sat_add_ji_to_j2i.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_j2i_sat_add_ji_to_j2i(const struct libj2_j2i *a, intmax_t b, struct libj2_j2i *res);
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_j2i_sat_lsh.c b/libj2_j2i_sat_lsh.c
new file mode 100644
index 0000000..49f5818
--- /dev/null
+++ b/libj2_j2i_sat_lsh.c
@@ -0,0 +1,17 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_j2i_sat_lsh(struct libj2_j2i *a, unsigned b);
+/* TODO Add man pages
+ * libj2_j2i_sat_lsh
+ * libj2_j2i_sat_lsh_to_j2i
+ * libj2_ji_sat_lsh_to_j2i
+ */
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_j2i_sat_lsh_to_j2i.3 b/libj2_j2i_sat_lsh_to_j2i.3
new file mode 120000
index 0000000..ea2743b
--- /dev/null
+++ b/libj2_j2i_sat_lsh_to_j2i.3
@@ -0,0 +1 @@
+libj2_j2i_sat_lsh.3 \ No newline at end of file
diff --git a/libj2_j2i_sat_lsh_to_j2i.c b/libj2_j2i_sat_lsh_to_j2i.c
new file mode 100644
index 0000000..476f2e5
--- /dev/null
+++ b/libj2_j2i_sat_lsh_to_j2i.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_j2i_sat_lsh_to_j2i(const struct libj2_j2i *a, unsigned b, struct libj2_j2i *res);
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_j2i_sat_rsub_j2i.3 b/libj2_j2i_sat_rsub_j2i.3
new file mode 120000
index 0000000..5200234
--- /dev/null
+++ b/libj2_j2i_sat_rsub_j2i.3
@@ -0,0 +1 @@
+libj2_j2i_sat_sub_j2i.3 \ No newline at end of file
diff --git a/libj2_j2i_sat_rsub_j2i.c b/libj2_j2i_sat_rsub_j2i.c
new file mode 100644
index 0000000..3d7853f
--- /dev/null
+++ b/libj2_j2i_sat_rsub_j2i.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_j2i_sat_rsub_j2i(struct libj2_j2i *a, const struct libj2_j2i *b);
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_j2i_sat_rsub_ji.3 b/libj2_j2i_sat_rsub_ji.3
new file mode 120000
index 0000000..5200234
--- /dev/null
+++ b/libj2_j2i_sat_rsub_ji.3
@@ -0,0 +1 @@
+libj2_j2i_sat_sub_j2i.3 \ No newline at end of file
diff --git a/libj2_j2i_sat_rsub_ji.c b/libj2_j2i_sat_rsub_ji.c
new file mode 100644
index 0000000..91dfc5f
--- /dev/null
+++ b/libj2_j2i_sat_rsub_ji.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_j2i_sat_rsub_ji(struct libj2_j2i *a, intmax_t b);
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_j2i_sat_sub_j2i.c b/libj2_j2i_sat_sub_j2i.c
new file mode 100644
index 0000000..0ddda43
--- /dev/null
+++ b/libj2_j2i_sat_sub_j2i.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_j2i_sat_sub_j2i(struct libj2_j2i *a, const struct libj2_j2i *b);
+/* TODO Add man pages
+ * libj2_j2i_sat_sub_j2i
+ * libj2_j2i_sat_sub_j2i_to_j2i
+ * libj2_j2i_sat_sub_ji
+ * libj2_j2i_sat_sub_ji_to_j2i
+ * libj2_ji_sat_sub_j2i_to_j2i
+ * libj2_j2i_sat_rsub_j2i
+ * libj2_j2i_sat_rsub_ji
+ */
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_j2i_sat_sub_j2i_to_j2i.3 b/libj2_j2i_sat_sub_j2i_to_j2i.3
new file mode 120000
index 0000000..5200234
--- /dev/null
+++ b/libj2_j2i_sat_sub_j2i_to_j2i.3
@@ -0,0 +1 @@
+libj2_j2i_sat_sub_j2i.3 \ No newline at end of file
diff --git a/libj2_j2i_sat_sub_j2i_to_j2i.c b/libj2_j2i_sat_sub_j2i_to_j2i.c
new file mode 100644
index 0000000..27f39e1
--- /dev/null
+++ b/libj2_j2i_sat_sub_j2i_to_j2i.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_j2i_sat_sub_j2i_to_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b, struct libj2_j2i *res);
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_j2i_sat_sub_ji.3 b/libj2_j2i_sat_sub_ji.3
new file mode 120000
index 0000000..5200234
--- /dev/null
+++ b/libj2_j2i_sat_sub_ji.3
@@ -0,0 +1 @@
+libj2_j2i_sat_sub_j2i.3 \ No newline at end of file
diff --git a/libj2_j2i_sat_sub_ji.c b/libj2_j2i_sat_sub_ji.c
new file mode 100644
index 0000000..8747163
--- /dev/null
+++ b/libj2_j2i_sat_sub_ji.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_j2i_sat_sub_ji(struct libj2_j2i *a, intmax_t b);
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_j2i_sat_sub_ji_to_j2i.3 b/libj2_j2i_sat_sub_ji_to_j2i.3
new file mode 120000
index 0000000..5200234
--- /dev/null
+++ b/libj2_j2i_sat_sub_ji_to_j2i.3
@@ -0,0 +1 @@
+libj2_j2i_sat_sub_j2i.3 \ No newline at end of file
diff --git a/libj2_j2i_sat_sub_ji_to_j2i.c b/libj2_j2i_sat_sub_ji_to_j2i.c
new file mode 100644
index 0000000..6008108
--- /dev/null
+++ b/libj2_j2i_sat_sub_ji_to_j2i.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_j2i_sat_sub_ji_to_j2i(const struct libj2_j2i *a, intmax_t b, struct libj2_j2i *res);
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_ji_sat_add_j2i_to_j2i.3 b/libj2_ji_sat_add_j2i_to_j2i.3
new file mode 120000
index 0000000..02a6a62
--- /dev/null
+++ b/libj2_ji_sat_add_j2i_to_j2i.3
@@ -0,0 +1 @@
+libj2_j2i_sat_add_j2i.3 \ No newline at end of file
diff --git a/libj2_ji_sat_add_j2i_to_j2i.c b/libj2_ji_sat_add_j2i_to_j2i.c
new file mode 100644
index 0000000..b85d2bf
--- /dev/null
+++ b/libj2_ji_sat_add_j2i_to_j2i.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_ji_sat_add_j2i_to_j2i(intmax_t a, const struct libj2_j2i *b, struct libj2_j2i *res);
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_ji_sat_lsh_to_j2i.3 b/libj2_ji_sat_lsh_to_j2i.3
new file mode 120000
index 0000000..ea2743b
--- /dev/null
+++ b/libj2_ji_sat_lsh_to_j2i.3
@@ -0,0 +1 @@
+libj2_j2i_sat_lsh.3 \ No newline at end of file
diff --git a/libj2_ji_sat_lsh_to_j2i.c b/libj2_ji_sat_lsh_to_j2i.c
new file mode 100644
index 0000000..9fc6b09
--- /dev/null
+++ b/libj2_ji_sat_lsh_to_j2i.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_ji_sat_lsh_to_j2i(intmax_t a, unsigned b, struct libj2_j2i *res);
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif
diff --git a/libj2_ji_sat_sub_j2i_to_j2i.3 b/libj2_ji_sat_sub_j2i_to_j2i.3
new file mode 120000
index 0000000..5200234
--- /dev/null
+++ b/libj2_ji_sat_sub_j2i_to_j2i.3
@@ -0,0 +1 @@
+libj2_j2i_sat_sub_j2i.3 \ No newline at end of file
diff --git a/libj2_ji_sat_sub_j2i_to_j2i.c b/libj2_ji_sat_sub_j2i_to_j2i.c
new file mode 100644
index 0000000..f214305
--- /dev/null
+++ b/libj2_ji_sat_sub_j2i_to_j2i.c
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+extern inline void libj2_ji_sat_sub_j2i_to_j2i(intmax_t a, const struct libj2_j2i *b, struct libj2_j2i *res);
+
+
+#else
+
+CONST int main(void) { return 0; } /* TODO test */
+
+#endif