aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2024-01-29 07:32:29 +0100
committerMattias Andrée <maandree@kth.se>2024-01-29 17:38:32 +0100
commitcb4b8137902b7c89872f8face7b47704f932b807 (patch)
treeaff0ef17c94de69cb818b4635338b792cdae534a
parentAdd libsimple_generate_seed and libsimple_srand (diff)
downloadlibsimple-cb4b8137902b7c89872f8face7b47704f932b807.tar.gz
libsimple-cb4b8137902b7c89872f8face7b47704f932b807.tar.bz2
libsimple-cb4b8137902b7c89872f8face7b47704f932b807.tar.xz
Add to*, *diff, *abs, *uabs, and random_{bits,float,signed,unsigned}
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--Makefile53
-rw-r--r--abs.c18
-rw-r--r--diff.c18
-rw-r--r--habs.c18
-rw-r--r--hdiff.c18
-rw-r--r--hhabs.c18
-rw-r--r--hhdiff.c18
-rw-r--r--i16abs.c18
-rw-r--r--i16diff.c18
-rw-r--r--i32abs.c18
-rw-r--r--i32diff.c18
-rw-r--r--i64abs.c18
-rw-r--r--i64diff.c18
-rw-r--r--i8abs.c18
-rw-r--r--i8diff.c18
-rw-r--r--imaxabs.c18
-rw-r--r--imaxdiff.c18
-rw-r--r--iptrabs.c18
-rw-r--r--iptrdiff.c18
-rw-r--r--labs.c18
-rw-r--r--ldiff.c18
-rw-r--r--libsimple.h1
-rw-r--r--libsimple/abs.h196
-rw-r--r--libsimple/random.h7
-rw-r--r--llabs.c18
-rw-r--r--lldiff.c18
-rw-r--r--random_bits.c34
-rw-r--r--random_float.c58
-rw-r--r--random_signed.c35
-rw-r--r--random_unsigned.c40
-rw-r--r--toi.c18
-rw-r--r--toi16.c18
-rw-r--r--toi32.c18
-rw-r--r--toi64.c18
-rw-r--r--toi8.c18
-rw-r--r--toih.c18
-rw-r--r--toihh.c18
-rw-r--r--toil.c18
-rw-r--r--toill.c18
-rw-r--r--toimax.c18
-rw-r--r--toiptr.c18
-rw-r--r--toiz.c18
-rw-r--r--u16abs.c18
-rw-r--r--u32abs.c18
-rw-r--r--u64abs.c18
-rw-r--r--u8abs.c18
-rw-r--r--uabs.c18
-rw-r--r--uhabs.c18
-rw-r--r--uhhabs.c18
-rw-r--r--ulabs.c18
-rw-r--r--ullabs.c18
-rw-r--r--umaxabs.c18
-rw-r--r--uptrabs.c18
-rw-r--r--uzabs.c18
-rw-r--r--zabs.c18
-rw-r--r--zdiff.c18
56 files changed, 1288 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 38f2537..4a8a324 100644
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,7 @@ LIB_NAME = simple
SUBHDR =\
+ libsimple/abs.h\
libsimple/aligned_alloc.h\
libsimple/aligned_allocz.h\
libsimple/aligned_memdup.h\
@@ -65,6 +66,7 @@ HDR =\
common.h
OBJ =\
+ abs.o\
aligned_allocn.o\
aligned_allocz.o\
aligned_alloczn.o\
@@ -89,6 +91,7 @@ OBJ =\
close_range.o\
cmptimespec.o\
cmptimeval.o\
+ diff.o\
difftimespec.o\
difftimeval.o\
doubletotimespec.o\
@@ -229,8 +232,28 @@ OBJ =\
getenv_e.o\
getenv_ne.o\
gmtime.o\
+ habs.o\
+ hdiff.o\
+ hhabs.o\
+ hhdiff.o\
+ i16abs.o\
+ i16diff.o\
+ i32abs.o\
+ i32diff.o\
+ i64abs.o\
+ i64diff.o\
+ i8abs.o\
+ i8diff.o\
+ imaxabs.o\
+ imaxdiff.o\
inchrcaseset.o\
inchrset.o\
+ iptrabs.o\
+ iptrdiff.o\
+ labs.o\
+ ldiff.o\
+ llabs.o\
+ lldiff.o\
localtime.o\
mallocn.o\
mallocz.o\
@@ -299,6 +322,10 @@ OBJ =\
pvallocn.o\
pvallocz.o\
pvalloczn.o\
+ random_bits.o\
+ random_float.o\
+ random_signed.o\
+ random_unsigned.o\
rawmemcasechr.o\
rawmemcasechr_inv.o\
rawmemccpy.o\
@@ -430,7 +457,31 @@ OBJ =\
timeval2timespec.o\
timevaltodouble.o\
timevaltostr.o\
+ toi.o\
+ toi16.o\
+ toi32.o\
+ toi64.o\
+ toi8.o\
+ toih.o\
+ toihh.o\
+ toil.o\
+ toill.o\
+ toimax.o\
+ toiptr.o\
+ toiz.o\
+ u16abs.o\
+ u32abs.o\
+ u64abs.o\
+ u8abs.o\
+ uabs.o\
+ uhabs.o\
+ uhhabs.o\
+ ulabs.o\
+ ullabs.o\
+ umaxabs.o\
unlist.o\
+ uptrabs.o\
+ uzabs.o\
valigned_allocn.o\
valigned_reallocfn.o\
valloc.o\
@@ -456,6 +507,8 @@ OBJ =\
wcsndup.o\
weprintf.o\
wmemdup.o\
+ zabs.o\
+ zdiff.o\
libsimple.o
MAN0 =\
diff --git a/abs.c b/abs.c
new file mode 100644
index 0000000..768a9f6
--- /dev/null
+++ b/abs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned int libsimple_abs(int, int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/diff.c b/diff.c
new file mode 100644
index 0000000..ca556c5
--- /dev/null
+++ b/diff.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned int libsimple_diff(int, int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/habs.c b/habs.c
new file mode 100644
index 0000000..cdfaf70
--- /dev/null
+++ b/habs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned short int libsimple_habs(short int, short int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/hdiff.c b/hdiff.c
new file mode 100644
index 0000000..89a865b
--- /dev/null
+++ b/hdiff.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned short int libsimple_hdiff(short int, short int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/hhabs.c b/hhabs.c
new file mode 100644
index 0000000..cc43287
--- /dev/null
+++ b/hhabs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned char libsimple_hhabs(signed char, signed char);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/hhdiff.c b/hhdiff.c
new file mode 100644
index 0000000..bfebfd6
--- /dev/null
+++ b/hhdiff.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned char libsimple_hhdiff(signed char, signed char);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/i16abs.c b/i16abs.c
new file mode 100644
index 0000000..1d9e61f
--- /dev/null
+++ b/i16abs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uint_least16_t libsimple_i16abs(int_least16_t, int_least16_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/i16diff.c b/i16diff.c
new file mode 100644
index 0000000..f8ac7b1
--- /dev/null
+++ b/i16diff.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uint_least16_t libsimple_i16diff(int_least16_t, int_least16_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/i32abs.c b/i32abs.c
new file mode 100644
index 0000000..9288e8b
--- /dev/null
+++ b/i32abs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uint_least32_t libsimple_i32abs(int_least32_t, int_least32_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/i32diff.c b/i32diff.c
new file mode 100644
index 0000000..32a545e
--- /dev/null
+++ b/i32diff.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uint_least32_t libsimple_i32diff(int_least32_t, int_least32_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/i64abs.c b/i64abs.c
new file mode 100644
index 0000000..72b770c
--- /dev/null
+++ b/i64abs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uint_least64_t libsimple_i64abs(int_least64_t, int_least64_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/i64diff.c b/i64diff.c
new file mode 100644
index 0000000..35a5e3c
--- /dev/null
+++ b/i64diff.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uint_least64_t libsimple_i64diff(int_least64_t, int_least64_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/i8abs.c b/i8abs.c
new file mode 100644
index 0000000..ea271a9
--- /dev/null
+++ b/i8abs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uint_least8_t libsimple_i8abs(int_least8_t, int_least8_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/i8diff.c b/i8diff.c
new file mode 100644
index 0000000..cb4086a
--- /dev/null
+++ b/i8diff.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uint_least8_t libsimple_i8diff(int_least8_t, int_least8_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/imaxabs.c b/imaxabs.c
new file mode 100644
index 0000000..dd50b78
--- /dev/null
+++ b/imaxabs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uintmax_t libsimple_imaxabs(intmax_t, intmax_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/imaxdiff.c b/imaxdiff.c
new file mode 100644
index 0000000..0555847
--- /dev/null
+++ b/imaxdiff.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uintmax_t libsimple_imaxdiff(intmax_t, intmax_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/iptrabs.c b/iptrabs.c
new file mode 100644
index 0000000..cd7088f
--- /dev/null
+++ b/iptrabs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uintptr_t libsimple_iptrabs(intptr_t, intptr_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/iptrdiff.c b/iptrdiff.c
new file mode 100644
index 0000000..fc406ef
--- /dev/null
+++ b/iptrdiff.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uintptr_t libsimple_iptrdiff(intptr_t, intptr_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/labs.c b/labs.c
new file mode 100644
index 0000000..9825fd1
--- /dev/null
+++ b/labs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned long int libsimple_labs(long int, long int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/ldiff.c b/ldiff.c
new file mode 100644
index 0000000..5a63843
--- /dev/null
+++ b/ldiff.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned long int libsimple_ldiff(long int, long int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/libsimple.h b/libsimple.h
index 1cd7806..bdfc7c7 100644
--- a/libsimple.h
+++ b/libsimple.h
@@ -166,6 +166,7 @@
#include "libsimple/strtoint.h"
#include "libsimple/search.h"
#include "libsimple/random.h"
+#include "libsimple/abs.h"
/**
diff --git a/libsimple/abs.h b/libsimple/abs.h
new file mode 100644
index 0000000..c1a9123
--- /dev/null
+++ b/libsimple/abs.h
@@ -0,0 +1,196 @@
+/* See LICENSE file for copyright and license details. */
+
+/* TODO man, doc, test */
+
+
+/*
+ * How to calculate the difference between two signed integers
+ * is not obvious, as the result must be unsigned to avoid
+ * overflow. The solution is to first covert the number to
+ * an unsigned type. Doing this ensure either that the value
+ * is unmodified or will be set the maximum value the unsigned
+ * type can store plus 1 plus the original negative value —
+ * it wraps around just just like if two's completement was
+ * used and the bits simply copied, regardless of how signed
+ * integers are actually stored. Now the subtraction will
+ * work adventurously without any overflow or the subtraction
+ * will overflow to the correct value. For example, say
+ * we are working with 8-bit integers, calculating (−1) − (−4)
+ * works out like so:
+ * (−1) − (−4)
+ * = (256 − 1) − (256 − 4)
+ * = 255 − 252
+ * = 3
+ * and calculating 5 − (−5) like so:
+ * 5 − (−5)
+ * ≡ 5 − (256 − 5)
+ * = 5 − 251
+ * ≡ 256 + (5 − 251)
+ * = 256 + (−246)
+ * = 256 − 246
+ * = 10
+ * Importantly, doing the convertion to unsigned type after
+ * the subtraction result in unspecified behaviour as
+ * signed integer overflow is unspecified behaviour.
+ */
+
+
+#define LIBSIMPLE_DIFF_(UTYPE, MAX, MIN) (UTYPE)((UTYPE)(MAX) - (UTYPE)(MIN))
+#define LIBSIMPLE_IABS_(UTYPE, A, B) ((A) > (B) ? LIBSIMPLE_DIFF_(UTYPE, (A), (B)) : LIBSIMPLE_DIFF_(UTYPE, (B), (A)))
+#define LIBSIMPLE_UABS_(UTYPE, A, B) ((UTYPE)((A) > (B) ? (A) - (B) : (B) - (A)))
+#define LIBSIMPLE_SIGN_(UTYPE, STYPE, VALUE) ((VALUE) >> (sizeof(UTYPE) * CHAR_BIT - 1) ? (STYPE)(VALUE) : -(STYPE)-(VALUE))
+
+
+inline unsigned char libsimple_hhdiff(signed char max, signed char min)
+{ return LIBSIMPLE_DIFF_(unsigned char, max, min); }
+
+inline unsigned short int libsimple_hdiff(short int max, short int min)
+{ return LIBSIMPLE_DIFF_(unsigned short int, max, min); }
+
+inline unsigned int libsimple_diff(int max, int min)
+{ return LIBSIMPLE_DIFF_(unsigned int, max, min); }
+
+inline unsigned long int libsimple_ldiff(long int max, long int min)
+{ return LIBSIMPLE_DIFF_(unsigned long int, max, min); }
+
+inline unsigned long long int libsimple_lldiff(long long int max, long long int min)
+{ return LIBSIMPLE_DIFF_(unsigned long long int, max, min); }
+
+inline size_t libsimple_zdiff(ssize_t max, ssize_t min)
+{ return LIBSIMPLE_DIFF_(size_t, max, min); }
+
+inline uint_least8_t libsimple_i8diff(int_least8_t max, int_least8_t min)
+{ return LIBSIMPLE_DIFF_(uint_least8_t, max, min); }
+
+inline uint_least16_t libsimple_i16diff(int_least16_t max, int_least16_t min)
+{ return LIBSIMPLE_DIFF_(uint_least16_t, max, min); }
+
+inline uint_least32_t libsimple_i32diff(int_least32_t max, int_least32_t min)
+{ return LIBSIMPLE_DIFF_(uint_least32_t, max, min); }
+
+inline uint_least64_t libsimple_i64diff(int_least64_t max, int_least64_t min)
+{ return LIBSIMPLE_DIFF_(uint_least64_t, max, min); }
+
+inline uintmax_t libsimple_imaxdiff(intmax_t max, intmax_t min)
+{ return LIBSIMPLE_DIFF_(uintmax_t, max, min); }
+
+inline uintptr_t libsimple_iptrdiff(intptr_t max, intptr_t min)
+{ return LIBSIMPLE_DIFF_(uintptr_t, max, min); }
+
+
+inline unsigned char libsimple_hhabs(signed char a, signed char b)
+{ return LIBSIMPLE_IABS_(unsigned char, a, b); }
+
+inline unsigned short int libsimple_habs(short int a, short int b)
+{ return LIBSIMPLE_IABS_(unsigned short int, a, b); }
+
+inline unsigned int libsimple_abs(int a, int b)
+{ return LIBSIMPLE_IABS_(unsigned int, a, b); }
+
+inline unsigned long int libsimple_labs(long int a, long int b)
+{ return LIBSIMPLE_IABS_(unsigned long int, a, b); }
+
+inline unsigned long long int libsimple_llabs(long long int a, long long int b)
+{ return LIBSIMPLE_IABS_(unsigned long long int, a, b); }
+
+inline size_t libsimple_zabs(ssize_t a, ssize_t b)
+{ return LIBSIMPLE_IABS_(size_t, a, b); }
+
+inline uint_least8_t libsimple_i8abs(int_least8_t a, int_least8_t b)
+{ return LIBSIMPLE_IABS_(uint_least8_t, a, b); }
+
+inline uint_least16_t libsimple_i16abs(int_least16_t a, int_least16_t b)
+{ return LIBSIMPLE_IABS_(uint_least16_t, a, b); }
+
+inline uint_least32_t libsimple_i32abs(int_least32_t a, int_least32_t b)
+{ return LIBSIMPLE_IABS_(uint_least32_t, a, b); }
+
+inline uint_least64_t libsimple_i64abs(int_least64_t a, int_least64_t b)
+{ return LIBSIMPLE_IABS_(uint_least64_t, a, b); }
+
+inline uintmax_t libsimple_imaxabs(intmax_t a, intmax_t b)
+{ return LIBSIMPLE_IABS_(uintmax_t, a, b); }
+
+inline uintptr_t libsimple_iptrabs(intptr_t a, intptr_t b)
+{ return LIBSIMPLE_IABS_(uintptr_t, a, b); }
+
+
+inline unsigned char libsimple_uhhabs(unsigned char a, unsigned char b)
+{ return LIBSIMPLE_UABS_(unsigned char, a, b); }
+
+inline unsigned short int libsimple_uhabs(unsigned short int a, unsigned short int b)
+{ return LIBSIMPLE_UABS_(unsigned short int, a, b); }
+
+inline unsigned int libsimple_uabs(unsigned int a, unsigned int b)
+{ return LIBSIMPLE_UABS_(unsigned int, a, b); }
+
+inline unsigned long int libsimple_ulabs(unsigned long int a, unsigned long int b)
+{ return LIBSIMPLE_UABS_(unsigned long int, a, b); }
+
+inline unsigned long long int libsimple_ullabs(unsigned long long int a, unsigned long long int b)
+{ return LIBSIMPLE_UABS_(unsigned long long int, a, b); }
+
+inline size_t libsimple_uzabs(size_t a, size_t b)
+{ return LIBSIMPLE_UABS_(size_t, a, b); }
+
+inline uint_least8_t libsimple_u8abs(uint_least8_t a, uint_least8_t b)
+{ return LIBSIMPLE_UABS_(uint_least8_t, a, b); }
+
+inline uint_least16_t libsimple_u16abs(uint_least16_t a, uint_least16_t b)
+{ return LIBSIMPLE_UABS_(uint_least16_t, a, b); }
+
+inline uint_least32_t libsimple_u32abs(uint_least32_t a, uint_least32_t b)
+{ return LIBSIMPLE_UABS_(uint_least32_t, a, b); }
+
+inline uint_least64_t libsimple_u64abs(uint_least64_t a, uint_least64_t b)
+{ return LIBSIMPLE_UABS_(uint_least64_t, a, b); }
+
+inline uintmax_t libsimple_umaxabs(uintmax_t a, uintmax_t b)
+{ return LIBSIMPLE_UABS_(uintmax_t, a, b); }
+
+inline uintptr_t libsimple_uptrabs(uintptr_t a, uintptr_t b)
+{ return LIBSIMPLE_UABS_(uintptr_t, a, b); }
+
+
+inline signed char libsimple_toihh(unsigned char value)
+{ return LIBSIMPLE_SIGN_(unsigned char, signed char, value); }
+
+inline short int libsimple_toih(unsigned short int value)
+{ return LIBSIMPLE_SIGN_(unsigned short int, short int, value); }
+
+inline int libsimple_toi(unsigned int value)
+{ return LIBSIMPLE_SIGN_(unsigned int, int, value); }
+
+inline long int libsimple_toil(unsigned long int value)
+{ return LIBSIMPLE_SIGN_(unsigned long int, long int, value); }
+
+inline long long int libsimple_toill(unsigned long long int value)
+{ return LIBSIMPLE_SIGN_(unsigned long long int, long long int, value); }
+
+inline ssize_t libsimple_toiz(size_t value)
+{ return LIBSIMPLE_SIGN_(size_t, ssize_t, value); }
+
+inline int_least8_t libsimple_toi8(uint_least8_t value)
+{ return LIBSIMPLE_SIGN_(uint_least8_t, int_least8_t, value); }
+
+inline int_least16_t libsimple_toi16(uint_least16_t value)
+{ return LIBSIMPLE_SIGN_(uint_least16_t, int_least16_t, value); }
+
+inline int_least32_t libsimple_toi32(uint_least32_t value)
+{ return LIBSIMPLE_SIGN_(uint_least32_t, int_least32_t, value); }
+
+inline int_least64_t libsimple_toi64(uint_least64_t value)
+{ return LIBSIMPLE_SIGN_(uint_least32_t, int_least32_t, value); }
+
+inline intmax_t libsimple_toimax(uintmax_t value)
+{ return LIBSIMPLE_SIGN_(uintmax_t, intmax_t, value); }
+
+inline intptr_t libsimple_toiptr(uintptr_t value)
+{ return LIBSIMPLE_SIGN_(uintptr_t, intptr_t, value); }
+
+
+
+#undef LIBSIMPLE_DIFF_
+#undef LIBSIMPLE_IABS_
+#undef LIBSIMPLE_UABS_
+#undef LIBSIMPLE_SIGN_
diff --git a/libsimple/random.h b/libsimple/random.h
index 3c09d7a..a786661 100644
--- a/libsimple/random.h
+++ b/libsimple/random.h
@@ -20,3 +20,10 @@ libsimple_srand(void) /* TODO add man page */
{
srand(libsimple_generate_seed());
}
+
+
+/* TODO doc, man */
+uintmax_t libsimple_random_bits(size_t bits, void *unused);
+uintmax_t libsimple_random_unsigned(uintmax_t (*rng)(size_t bits, void *user), void *user, uintmax_t min, uintmax_t max);
+intmax_t libsimple_random_signed(uintmax_t (*rng)(size_t bits, void *user), void *user, intmax_t min, intmax_t max);
+long double libsimple_random_float(uintmax_t (*rng)(size_t bits, void *user), void *user, long double min, long double postmax);
diff --git a/llabs.c b/llabs.c
new file mode 100644
index 0000000..9a8a3dc
--- /dev/null
+++ b/llabs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned long long int libsimple_llabs(long long int, long long int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/lldiff.c b/lldiff.c
new file mode 100644
index 0000000..d8d1864
--- /dev/null
+++ b/lldiff.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned long long int libsimple_lldiff(long long int, long long int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/random_bits.c b/random_bits.c
new file mode 100644
index 0000000..528b09e
--- /dev/null
+++ b/random_bits.c
@@ -0,0 +1,34 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+uintmax_t
+libsimple_random_bits(size_t bits, void *unused)
+{
+ uintmax_t ret = 0;
+
+ while (bits >= 8) {
+ ret <<= 8;
+ ret |= (uintmax_t)(rand() & 0xFF);
+ bits -= 8;
+ }
+
+ ret <<= bits;
+ ret |= (uintmax_t)(rand() & ((1 << bits) - 1));
+
+ (void) unused;
+ return ret;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/random_float.c b/random_float.c
new file mode 100644
index 0000000..b4b6557
--- /dev/null
+++ b/random_float.c
@@ -0,0 +1,58 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+#include <math.h>
+
+
+long double
+libsimple_random_float(uintmax_t (*rng)(size_t bits, void *user), void *user, long double min, long double postmax) /* TODO add test */
+{
+ long double range, offset, mantissa, value;
+ uintmax_t r;
+ int exp;
+ size_t bits;
+
+ if (min < postmax) {
+ range = postmax - min;
+ offset = min;
+ } else if (min > postmax) {
+ range = min - postmax;
+ offset = postmax;
+ } else {
+ return min;
+ }
+
+ mantissa = frexpl(range, &exp);
+ do {
+ bits = sizeof(uintmax_t) * CHAR_BIT;
+ r = (*rng)(bits, user);
+ while (bits && (r & 1)) {
+ exp -= 1;
+ bits -= 1;
+ r >>= 1;
+ }
+ } while (!bits);
+
+ bits = sizeof(uintmax_t) * CHAR_BIT;
+ r = (*rng)(bits, user);
+ value = (long double)r;
+ value = fmal(value, 0.5, 0.5);
+ value = ldexpl(value, -(int)bits);
+
+ value = ldexpl(value, exp);
+ value *= mantissa;
+ return value + offset;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/random_signed.c b/random_signed.c
new file mode 100644
index 0000000..13d5f3b
--- /dev/null
+++ b/random_signed.c
@@ -0,0 +1,35 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+intmax_t
+libsimple_random_signed(uintmax_t (*rng)(size_t bits, void *user), void *user, intmax_t min, intmax_t max) /* TODO add test */
+{
+ uintmax_t range, offset, t, r;
+ size_t bits = 0;
+
+ range = libsimple_imaxabs(max, min);
+ offset = (uintmax_t)MIN(min, max);
+
+ for (t = range; t; t >>= 1)
+ bits += 1;
+
+ do {
+ r = (*rng)(bits, user);
+ } while (r > range);
+
+ return libsimple_toimax(r + offset);
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/random_unsigned.c b/random_unsigned.c
new file mode 100644
index 0000000..f39392d
--- /dev/null
+++ b/random_unsigned.c
@@ -0,0 +1,40 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+uintmax_t
+libsimple_random_unsigned(uintmax_t (*rng)(size_t bits, void *user), void *user, uintmax_t min, uintmax_t max) /* TODO add test */
+{
+ uintmax_t range, offset, t, r;
+ size_t bits = 0;
+
+ if (min < max) {
+ range = max - min;
+ offset = min;
+ } else {
+ range = min - max;
+ offset = max;
+ }
+
+ for (t = range; t; t >>= 1)
+ bits += 1;
+
+ do {
+ r = (*rng)(bits, user);
+ } while (r > range);
+
+ return r + offset;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/toi.c b/toi.c
new file mode 100644
index 0000000..4026885
--- /dev/null
+++ b/toi.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline int libsimple_toi(unsigned int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/toi16.c b/toi16.c
new file mode 100644
index 0000000..e5d93dd
--- /dev/null
+++ b/toi16.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline int_least16_t libsimple_toi16(uint_least16_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/toi32.c b/toi32.c
new file mode 100644
index 0000000..bf44a6c
--- /dev/null
+++ b/toi32.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline int_least32_t libsimple_toi32(uint_least32_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/toi64.c b/toi64.c
new file mode 100644
index 0000000..b2a92ab
--- /dev/null
+++ b/toi64.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline int_least64_t libsimple_toi64(uint_least64_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/toi8.c b/toi8.c
new file mode 100644
index 0000000..53bda55
--- /dev/null
+++ b/toi8.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline int_least8_t libsimple_toi8(uint_least8_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/toih.c b/toih.c
new file mode 100644
index 0000000..954ff48
--- /dev/null
+++ b/toih.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline short int libsimple_toih(unsigned short int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/toihh.c b/toihh.c
new file mode 100644
index 0000000..358d426
--- /dev/null
+++ b/toihh.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline signed char libsimple_toihh(unsigned char);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/toil.c b/toil.c
new file mode 100644
index 0000000..c70bc37
--- /dev/null
+++ b/toil.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline long int libsimple_toil(unsigned long int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/toill.c b/toill.c
new file mode 100644
index 0000000..4566dc0
--- /dev/null
+++ b/toill.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline long long int libsimple_toill(unsigned long long int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/toimax.c b/toimax.c
new file mode 100644
index 0000000..5525999
--- /dev/null
+++ b/toimax.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline intmax_t libsimple_toimax(uintmax_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/toiptr.c b/toiptr.c
new file mode 100644
index 0000000..c85ec1b
--- /dev/null
+++ b/toiptr.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline intptr_t libsimple_toiptr(uintptr_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/toiz.c b/toiz.c
new file mode 100644
index 0000000..1e48aff
--- /dev/null
+++ b/toiz.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline ssize_t libsimple_toiz(size_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/u16abs.c b/u16abs.c
new file mode 100644
index 0000000..f7e87c3
--- /dev/null
+++ b/u16abs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uint_least16_t libsimple_u16abs(uint_least16_t, uint_least16_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/u32abs.c b/u32abs.c
new file mode 100644
index 0000000..06861b5
--- /dev/null
+++ b/u32abs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uint_least32_t libsimple_u32abs(uint_least32_t, uint_least32_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/u64abs.c b/u64abs.c
new file mode 100644
index 0000000..29e9fb7
--- /dev/null
+++ b/u64abs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uint_least64_t libsimple_u64abs(uint_least64_t, uint_least64_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/u8abs.c b/u8abs.c
new file mode 100644
index 0000000..827826a
--- /dev/null
+++ b/u8abs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uint_least8_t libsimple_u8abs(uint_least8_t, uint_least8_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/uabs.c b/uabs.c
new file mode 100644
index 0000000..2a5e82b
--- /dev/null
+++ b/uabs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned int libsimple_uabs(unsigned int, unsigned int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/uhabs.c b/uhabs.c
new file mode 100644
index 0000000..543f04c
--- /dev/null
+++ b/uhabs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned short int libsimple_uhabs(unsigned short int, unsigned short int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/uhhabs.c b/uhhabs.c
new file mode 100644
index 0000000..d00ac96
--- /dev/null
+++ b/uhhabs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned char libsimple_uhhabs(unsigned char, unsigned char);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/ulabs.c b/ulabs.c
new file mode 100644
index 0000000..d806857
--- /dev/null
+++ b/ulabs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned long int libsimple_ulabs(unsigned long int, unsigned long int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/ullabs.c b/ullabs.c
new file mode 100644
index 0000000..43c32c0
--- /dev/null
+++ b/ullabs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline unsigned long long int libsimple_ullabs(unsigned long long int, unsigned long long int);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/umaxabs.c b/umaxabs.c
new file mode 100644
index 0000000..f5b1128
--- /dev/null
+++ b/umaxabs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uintmax_t libsimple_umaxabs(uintmax_t, uintmax_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/uptrabs.c b/uptrabs.c
new file mode 100644
index 0000000..5ec5ceb
--- /dev/null
+++ b/uptrabs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline uintptr_t libsimple_uptrabs(uintptr_t, uintptr_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/uzabs.c b/uzabs.c
new file mode 100644
index 0000000..49d31fe
--- /dev/null
+++ b/uzabs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline size_t libsimple_uzabs(size_t, size_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/zabs.c b/zabs.c
new file mode 100644
index 0000000..4d7c43a
--- /dev/null
+++ b/zabs.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline size_t libsimple_zabs(ssize_t, ssize_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/zdiff.c b/zdiff.c
new file mode 100644
index 0000000..1e4bd60
--- /dev/null
+++ b/zdiff.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+extern inline size_t libsimple_zdiff(ssize_t, ssize_t);
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif