diff options
57 files changed, 3475 insertions, 36 deletions
@@ -203,7 +203,53 @@ OBJ =\ libj2_vmax_j2u_to_j2u.o\ libj2_vmin_j2u.o\ libj2_vmin_j2u_return.o\ - libj2_vmin_j2u_to_j2u.o + libj2_vmin_j2u_to_j2u.o\ + libj2_j2u_and_bit_to_j2u.o\ + libj2_j2u_and_bit.o\ + libj2_j2u_or_bit_to_j2u.o\ + libj2_j2u_or_bit.o\ + libj2_j2u_xor_bit_to_j2u.o\ + libj2_j2u_xor_bit.o\ + libj2_j2u_if_bit_to_j2u.o\ + libj2_j2u_if_bit.o\ + libj2_j2u_imply_bit_to_j2u.o\ + libj2_j2u_imply_bit.o\ + libj2_j2u_nand_bit_to_j2u.o\ + libj2_j2u_nand_bit.o\ + libj2_j2u_nor_bit_to_j2u.o\ + libj2_j2u_nor_bit.o\ + libj2_j2u_xnor_bit_to_j2u.o\ + libj2_j2u_xnor_bit.o\ + libj2_j2u_nif_bit_to_j2u.o\ + libj2_j2u_nif_bit.o\ + libj2_j2u_nimply_bit_to_j2u.o\ + libj2_j2u_nimply_bit.o\ + libj2_clz_j2u.o\ + libj2_clo_j2u.o\ + libj2_ctz_j2u.o\ + libj2_cto_j2u.o\ + libj2_co_j2u.o\ + libj2_cz_j2u.o\ + libj2_ffs_j2u.o\ + libj2_ffc_j2u.o\ + libj2_fls_j2u.o\ + libj2_flc_j2u.o\ + libj2_parity_j2u.o\ + libj2_kfs_j2u.o\ + libj2_kfs_j2u_to_j2u.o\ + libj2_kls_j2u.o\ + libj2_kls_j2u_to_j2u.o\ + libj2_cfs_j2u.o\ + libj2_cfs_j2u_to_j2u.o\ + libj2_cls_j2u.o\ + libj2_cls_j2u_to_j2u.o\ + libj2_sfc_j2u.o\ + libj2_sfc_j2u_to_j2u.o\ + libj2_slc_j2u.o\ + libj2_slc_j2u_to_j2u.o\ + libj2_j2u_has_j2u.o\ + libj2_j2u_has_ju.o\ + libj2_j2u_has_high_ju.o SUBHDR =\ libj2/constants.h\ @@ -212,6 +258,7 @@ SUBHDR =\ libj2/unsigned-comparsion.h\ libj2/bitwise-logic.h\ libj2/bit-shifting.h\ + libj2/bit-scanning.h\ libj2/sign-shifting.h\ libj2/addition.h\ libj2/subtraction.h\ @@ -9,10 +9,20 @@ #if 1 # if defined(__GNUC__) # define LIBJ2_USE_GCC_INTRINSIC_FUNCTIONS_ +# if !defined(__clang__) +# define LIBJ2_USE_GCC_PARITYG_ +# endif # endif #endif +#if defined(__GNUC__) +# define LIBJ2_PURE_ __attribute__((__pure__)) +#else +# define LIBJ2_PURE_ +#endif + + /** * The number of bits in an `uintmax_t` */ @@ -48,6 +58,7 @@ struct libj2_j2u { #include "libj2/unsigned-comparsion.h" #include "libj2/bitwise-logic.h" #include "libj2/bit-shifting.h" +#include "libj2/bit-scanning.h" #include "libj2/sign-shifting.h" #include "libj2/addition.h" #include "libj2/subtraction.h" @@ -58,5 +69,6 @@ struct libj2_j2u { #if defined(LIBJ2_USE_GCC_INTRINSIC_FUNCTIONS_) # undef LIBJ2_USE_GCC_INTRINSIC_FUNCTIONS_ #endif +#undef LIBJ2_PURE_ #endif diff --git a/libj2/bit-scanning.h b/libj2/bit-scanning.h new file mode 100644 index 0000000..963f2e2 --- /dev/null +++ b/libj2/bit-scanning.h @@ -0,0 +1,457 @@ +/* See LICENSE file for copyright and license details. */ +#ifndef LIBJ2_H +# error Do not include this header directly, include <libj2.h> instead +#endif + + +/** + * Get the number of leading zeroes in an + * unsigned double-max precision integer + * + * @param a The integer to inspect + * @return The number of zeroes after the most signficant set + * bit in `a`, `LIBJ2_J2U_BIT` if `a` has the value 0 + */ +LIBJ2_PURE_ inline unsigned +libj2_clz_j2u(const struct libj2_j2u *a) +{ + uintmax_t x; + unsigned r, n; + if (a->high) { + x = a->high; + r = 0; + } else if (a->low) { + x = a->low; + r = LIBJ2_JU_BIT; + } else { + return LIBJ2_J2U_BIT; + } +#if defined(LIBJ2_USE_GCC_INTRINSIC_FUNCTIONS_) + n = (unsigned)__builtin_clzg(x); + return r + n; +#else + for (n = LIBJ2_JU_BIT; !((x >> --n) & 1U); r++); + return r; +#endif +} + + +/** + * Get the number of leading ones in an + * unsigned double-max precision integer + * + * @param a The integer to inspect + * @return The number of ones after the most signficant cleared + * bit in `a`, `LIBJ2_J2U_BIT` if all bits in `a` are set + */ +LIBJ2_PURE_ inline unsigned +libj2_clo_j2u(const struct libj2_j2u *a) +{ + return libj2_clz_j2u(&(struct libj2_j2u){.high = ~a->high, .low = ~a->low}); +} + + +/** + * Get the number of trailing zeroes in an + * unsigned double-max precision integer + * + * @param a The integer to inspect + * @return The number of zeroes before the least signficant set + * bit in `a`, `LIBJ2_J2U_BIT` if `a` has the value 0 + */ +LIBJ2_PURE_ inline unsigned +libj2_ctz_j2u(const struct libj2_j2u *a) +{ + uintmax_t x; + unsigned r, n; + if (a->low) { + x = a->low; + r = 0; + } else if (a->high) { + x = a->high; + r = LIBJ2_JU_BIT; + } else { + return LIBJ2_J2U_BIT; + } +#if defined(LIBJ2_USE_GCC_INTRINSIC_FUNCTIONS_) + n = (unsigned)__builtin_ctzg(x); +#else + for (n = 0; !((x >> n) & 1U); n++); +#endif + return r + n; +} + + +/** + * Get the number of trailing ones in an + * unsigned double-max precision integer + * + * @param a The integer to inspect + * @return The number of ones before the leadt signficant cleared + * bit in `a`, `LIBJ2_J2U_BIT` if all bits in `a` are set + */ +LIBJ2_PURE_ inline unsigned +libj2_cto_j2u(const struct libj2_j2u *a) +{ + return libj2_ctz_j2u(&(struct libj2_j2u){.high = ~a->high, .low = ~a->low}); +} + + +/** + * Count the number of set bits in an + * unsigned double-max precision integer + * + * @param a The integer to inspect + * @return The number of set bits in `a` + */ +LIBJ2_PURE_ inline unsigned +libj2_co_j2u(const struct libj2_j2u *a) +{ +#if defined(LIBJ2_USE_GCC_INTRINSIC_FUNCTIONS_) + return (unsigned)__builtin_popcountg(a->high) + (unsigned)__builtin_popcountg(a->low); +#else + uintmax_t x, r = 0; +#if UINT64_MAX < UINTMAX_MAX + uintmax_t y; + for (y = a->low; y; y >>= 64) { + x = y & UINT64_MAX; +#else + x = a->high; +#endif + x = (x & UINTMAX_C(0x5555555555555555)) + ((x >> 1) & UINTMAX_C(0x5555555555555555)); + x = (x & UINTMAX_C(0x3333333333333333)) + ((x >> 2) & UINTMAX_C(0x3333333333333333)); + x = (x & UINTMAX_C(0x0F0F0F0F0F0F0F0F)) + ((x >> 4) & UINTMAX_C(0x0F0F0F0F0F0F0F0F)); + x = (x & UINTMAX_C(0x00FF00FF00FF00FF)) + ((x >> 8) & UINTMAX_C(0x00FF00FF00FF00FF)); + x = (x & UINTMAX_C(0x0000FFFF0000FFFF)) + ((x >> 16) & UINTMAX_C(0x0000FFFF0000FFFF)); + x = (x & UINTMAX_C(0x00000000FFFFFFFF)) + ((x >> 32) & UINTMAX_C(0x00000000FFFFFFFF)); + r += x; +#if UINT64_MAX < UINTMAX_MAX + } +#endif +#if UINT64_MAX < UINTMAX_MAX + for (y = a->low; y; y >>= 64) { + x = y & UINT64_MAX; +#else + x = a->low; +#endif + x = (x & UINTMAX_C(0x5555555555555555)) + ((x >> 1) & UINTMAX_C(0x5555555555555555)); + x = (x & UINTMAX_C(0x3333333333333333)) + ((x >> 2) & UINTMAX_C(0x3333333333333333)); + x = (x & UINTMAX_C(0x0F0F0F0F0F0F0F0F)) + ((x >> 4) & UINTMAX_C(0x0F0F0F0F0F0F0F0F)); + x = (x & UINTMAX_C(0x00FF00FF00FF00FF)) + ((x >> 8) & UINTMAX_C(0x00FF00FF00FF00FF)); + x = (x & UINTMAX_C(0x0000FFFF0000FFFF)) + ((x >> 16) & UINTMAX_C(0x0000FFFF0000FFFF)); + x = (x & UINTMAX_C(0x00000000FFFFFFFF)) + ((x >> 32) & UINTMAX_C(0x00000000FFFFFFFF)); + r += x; +#if UINT64_MAX < UINTMAX_MAX + } +#endif + return (unsigned)r; +#endif +} + + +/** + * Count the number of cleared bits in an + * unsigned double-max precision integer + * + * @param a The integer to inspect + * @return The number of cleared bits in `a` + */ +LIBJ2_PURE_ inline unsigned +libj2_cz_j2u(const struct libj2_j2u *a) +{ + return LIBJ2_J2U_BIT - libj2_co_j2u(a); +} + + +/** + * Get the index of the least significant set + * bit in an unsigned double-max precision integer + * + * @param a The integer to inspect + * @return The index, counting from index one + * at the least significant bit, of the + * least significant set bit in `a`, or + * 0 if no bit is set + */ +LIBJ2_PURE_ inline unsigned +libj2_ffs_j2u(const struct libj2_j2u *a) +{ + unsigned r = libj2_ctz_j2u(a); + return r == LIBJ2_J2U_BIT ? 0U : r + 1U; +} + + +/** + * Get the index of the least significant cleared + * bit in an unsigned double-max precision integer + * + * @param a The integer to inspect + * @return The index, counting from index one + * at the least significant bit, of the + * least significant cleared bit in `a`, + * or 0 if no bit is cleared + */ +LIBJ2_PURE_ inline unsigned +libj2_ffc_j2u(const struct libj2_j2u *a) +{ + return libj2_ffs_j2u(&(struct libj2_j2u){.high = ~a->high, .low = ~a->low}); +} + + +/** + * Get the index of the most significant set + * bit in an unsigned double-max precision integer + * + * @param a The integer to inspect + * @return The index, counting from index one + * at the least significant bit, of the + * most significant set bit in `a`, + * or 0 if no bit is set + */ +LIBJ2_PURE_ inline unsigned +libj2_fls_j2u(const struct libj2_j2u *a) +{ + unsigned r = libj2_clz_j2u(a); + return LIBJ2_J2U_BIT - r; +} + + +/** + * Get the index of the most significant cleared + * bit in an unsigned double-max precision integer + * + * @param a The integer to inspect + * @return The index, counting from index one + * at the least significant bit, of the + * most significant cleared bit in `a`, + * or 0 if no bit is cleared + */ +LIBJ2_PURE_ inline unsigned +libj2_flc_j2u(const struct libj2_j2u *a) +{ + return libj2_fls_j2u(&(struct libj2_j2u){.high = ~a->high, .low = ~a->low}); +} + + +/** + * Calculate the parity of the bits in + * an unsigned double-max precision integer + * + * @param a The integer to inspect + * @return 1 if the number of set bits in `a` + * is odd, 0 otherwise (if even) + */ +LIBJ2_PURE_ inline unsigned +libj2_parity_j2u(const struct libj2_j2u *a) +{ +#if defined(LIBJ2_USE_GCC_PARITYG_) + return (unsigned)(__builtin_parityg(a->high) ^ __builtin_parityg(a->low)); +#else + unsigned s = LIBJ2_JU_BIT >> 1; + uintmax_t x = a->high ^ a->low; + uintmax_t mask = ((uintmax_t)1 << s) - 1U; + while (s) { + x = (x ^ (x >> s)) & mask; + mask >>= s >>= 1; + } + return (unsigned)x; +#endif +} + + +/** + * Clears all bits in an unsigned double-max precision + * integer except the least significant set bit + * + * @param a The integer to modify; will be updated + */ +inline void +libj2_kfs_j2u(struct libj2_j2u *a) +{ + unsigned i = libj2_ffs_j2u(a); + if (i) + libj2_j2u_and_bit(a, i - 1U); +} + + +/** + * Clears all bits in an unsigned double-max precision + * integer except the least significant set bit + * + * @param a The integer to modify + * @param res Output parameter for the result + */ +inline void +libj2_kfs_j2u_to_j2u(const struct libj2_j2u *a, struct libj2_j2u *res) +{ + unsigned i = libj2_ffs_j2u(a); + if (i) + libj2_j2u_and_bit_to_j2u(a, i - 1U, res); + else + *res = *a; +} + + +/** + * Clears all bits in an unsigned double-max precision + * integer except the most significant set bit + * + * @param a The integer to modify; will be modified + */ +inline void +libj2_kls_j2u(struct libj2_j2u *a) +{ + unsigned i = libj2_fls_j2u(a); + if (i) + libj2_j2u_and_bit(a, i - 1U); +} + + +/** + * Clears all bits in an unsigned double-max precision + * integer except the most significant set bit + * + * @param a The integer to modify + * @param res Output parameter for the result + */ +inline void +libj2_kls_j2u_to_j2u(const struct libj2_j2u *a, struct libj2_j2u *res) +{ + unsigned i = libj2_fls_j2u(a); + if (i) + libj2_j2u_and_bit_to_j2u(a, i - 1U, res); + else + *res = *a; +} + + +/** + * Clear the least significant set bit in an + * unsigned double-max precision integer + * + * @param a The integer to modify; will be updated + */ +inline void +libj2_cfs_j2u(struct libj2_j2u *a) +{ + unsigned i = libj2_ffs_j2u(a); + if (i) + libj2_j2u_xor_bit(a, i - 1U); +} + + +/** + * Clear the least significant set bit in an + * unsigned double-max precision integer + * + * @param a The integer to modify + * @param res Output parameter for the result + */ +inline void +libj2_cfs_j2u_to_j2u(const struct libj2_j2u *a, struct libj2_j2u *res) +{ + unsigned i = libj2_ffs_j2u(a); + if (i) + libj2_j2u_xor_bit_to_j2u(a, i - 1U, res); + else + *res = *a; +} + + +/** + * Clear the most significant set bit in an + * unsigned double-max precision integer + * + * @param a The integer to modify; will be modified + */ +inline void +libj2_cls_j2u(struct libj2_j2u *a) +{ + unsigned i = libj2_fls_j2u(a); + if (i) + libj2_j2u_xor_bit(a, i - 1U); +} + + +/** + * Clear the most significant set bit in an + * unsigned double-max precision integer + * + * @param a The integer to modify + * @param res Output parameter for the result + */ +inline void +libj2_cls_j2u_to_j2u(const struct libj2_j2u *a, struct libj2_j2u *res) +{ + unsigned i = libj2_fls_j2u(a); + if (i) + libj2_j2u_xor_bit_to_j2u(a, i - 1U, res); + else + *res = *a; +} + + +/** + * Set the least significant cleared bit in an + * unsigned double-max precision integer + * + * @param a The integer to modify; will be updated + */ +inline void +libj2_sfc_j2u(struct libj2_j2u *a) +{ + unsigned i = libj2_ffc_j2u(a); + if (i) + libj2_j2u_or_bit(a, i - 1U); +} + + +/** + * Set the least significant cleared bit in an + * unsigned double-max precision integer + * + * @param a The integer to modify + * @param res Output parameter for the result + */ +inline void +libj2_sfc_j2u_to_j2u(const struct libj2_j2u *a, struct libj2_j2u *res) +{ + unsigned i = libj2_ffc_j2u(a); + if (i) + libj2_j2u_or_bit_to_j2u(a, i - 1U, res); + else + *res = *a; +} + + +/** + * Set the most significant cleared bit in an + * unsigned double-max precision integer + * + * @param a The integer to modify; will be modified + */ +inline void +libj2_slc_j2u(struct libj2_j2u *a) +{ + unsigned i = libj2_flc_j2u(a); + if (i) + libj2_j2u_or_bit(a, i - 1U); +} + + +/** + * Set the most significant cleared bit in an + * unsigned double-max precision integer + * + * @param a The integer to modify + * @param res Output parameter for the result + */ +inline void +libj2_slc_j2u_to_j2u(const struct libj2_j2u *a, struct libj2_j2u *res) +{ + unsigned i = libj2_flc_j2u(a); + if (i) + libj2_j2u_or_bit_to_j2u(a, i - 1U, res); + else + *res = *a; +} diff --git a/libj2/bitwise-logic.h b/libj2/bitwise-logic.h index 6ec362e..288994b 100644 --- a/libj2/bitwise-logic.h +++ b/libj2/bitwise-logic.h @@ -13,7 +13,7 @@ * 0 for the least significant bit * @return 1 if the bit is set, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_test_bit(const struct libj2_j2u *a, unsigned b) { if (b >= LIBJ2_J2U_BIT) @@ -34,7 +34,7 @@ libj2_j2u_test_bit(const struct libj2_j2u *a, unsigned b) * @return 1 if the two integers have set bits * in common, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_test_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) { return (a->high & b->high) || (a->low & b->low); @@ -51,7 +51,7 @@ libj2_j2u_test_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) * @return 1 if the two integers have set bits * in common, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_test_ju(const struct libj2_j2u *a, uintmax_t b) { return !!(a->low & b); @@ -68,7 +68,7 @@ libj2_j2u_test_ju(const struct libj2_j2u *a, uintmax_t b) * @return 1 if high part of `a` have set bits * in common with `b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_test_high_ju(const struct libj2_j2u *a, uintmax_t b) { return !!(a->high & b); @@ -978,3 +978,588 @@ libj2_ju_nif_j2u_to_j2u(uintmax_t a, const struct libj2_j2u *b, struct libj2_j2u { libj2_j2u_nimply_ju_to_j2u(b, a, res); } + + +/** + * Calculate the bitwise AND of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This clears all but the specified bit + * + * @param a The left-hand integer + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + * @param res Output parameter for the result + */ +inline void +libj2_j2u_and_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res) +{ + if (b >= LIBJ2_J2U_BIT) { + res->high = 0; + res->low = 0; + } else if (b >= LIBJ2_JU_BIT) { + res->high = a->high & ((uintmax_t)1 << (b - LIBJ2_JU_BIT)); + res->low = 0; + } else { + res->high = 0; + res->low = a->low & ((uintmax_t)1 << b); + } +} + + +/** + * Calculate the bitwise AND of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This clears all but the specified bit + * + * @param a The left-hand integer, also used as the + * output parameter for the result + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + */ +inline void +libj2_j2u_and_bit(struct libj2_j2u *a, unsigned b) +{ + libj2_j2u_and_bit_to_j2u(a, b, a); +} + + +/** + * Calculate the bitwise OR of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This sets the specified bit + * + * @param a The left-hand integer + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + * @param res Output parameter for the result + */ +inline void +libj2_j2u_or_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res) +{ + if (b >= LIBJ2_J2U_BIT) { + res->high = a->high; + res->low = a->low; + } else if (b >= LIBJ2_JU_BIT) { + res->high = a->high | ((uintmax_t)1 << (b - LIBJ2_JU_BIT)); + res->low = a->low; + } else { + res->high = a->high; + res->low = a->low | ((uintmax_t)1 << b); + } +} + + +/** + * Calculate the bitwise OR of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This sets the specified bit + * + * @param a The left-hand integer, also used as the + * output parameter for the result + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + */ +inline void +libj2_j2u_or_bit(struct libj2_j2u *a, unsigned b) +{ + if (b >= LIBJ2_JU_BIT) { + if (b >= LIBJ2_J2U_BIT) + return; + a->high |= (uintmax_t)1 << (b - LIBJ2_JU_BIT); + } else { + a->low |= (uintmax_t)1 << b; + } +} + + +/** + * Calculate the bitwise XOR of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This flips the specified bit + * + * @param a The left-hand integer + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + * @param res Output parameter for the result + */ +inline void +libj2_j2u_xor_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res) +{ + if (b >= LIBJ2_J2U_BIT) { + res->high = a->high; + res->low = a->low; + } else if (b >= LIBJ2_JU_BIT) { + res->high = a->high ^ ((uintmax_t)1 << (b - LIBJ2_JU_BIT)); + res->low = a->low; + } else { + res->high = a->high; + res->low = a->low ^ ((uintmax_t)1 << b); + } +} + + +/** + * Calculate the bitwise XOR of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This flips the specified bit + * + * @param a The left-hand integer, also used as the + * output parameter for the result + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + */ +inline void +libj2_j2u_xor_bit(struct libj2_j2u *a, unsigned b) +{ + if (b >= LIBJ2_JU_BIT) { + if (b >= LIBJ2_J2U_BIT) + return; + a->high ^= (uintmax_t)1 << (b - LIBJ2_JU_BIT); + } else { + a->low ^= (uintmax_t)1 << b; + } +} + + +/** + * Calculate the bitwise IF of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This sets all but the specified bit + * + * @param a The left-hand integer + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + * @param res Output parameter for the result + */ +inline void +libj2_j2u_if_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res) +{ + if (b >= LIBJ2_J2U_BIT) { + res->high = UINTMAX_MAX; + res->low = UINTMAX_MAX; + } else if (b >= LIBJ2_JU_BIT) { + res->high = a->high | ~((uintmax_t)1 << (b - LIBJ2_JU_BIT)); + res->low = UINTMAX_MAX; + } else { + res->high = UINTMAX_MAX; + res->low = a->low | ~((uintmax_t)1 << b); + } +} + + +/** + * Calculate the bitwise IF of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This sets all but the specified bit + * + * @param a The left-hand integer, also used as the + * output parameter for the result + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + */ +inline void +libj2_j2u_if_bit(struct libj2_j2u *a, unsigned b) +{ + libj2_j2u_if_bit_to_j2u(a, b, a); +} + + +/** + * Calculate the bitwise IMPLY of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This sets the specified bit and flips the rest + * + * @param a The left-hand integer + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + * @param res Output parameter for the result + */ +inline void +libj2_j2u_imply_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res) +{ + res->high = a->high ^ UINTMAX_MAX; + res->low = a->low ^ UINTMAX_MAX; + if (b >= LIBJ2_JU_BIT) { + if (b >= LIBJ2_J2U_BIT) + return; + res->high |= (uintmax_t)1 << (b - LIBJ2_JU_BIT); + } else { + res->low |= (uintmax_t)1 << b; + } +} + + +/** + * Calculate the bitwise IMPLY of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This sets the specified bit and flips the rest + * + * @param a The left-hand integer, also used as the + * output parameter for the result + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + */ +inline void +libj2_j2u_imply_bit(struct libj2_j2u *a, unsigned b) +{ + libj2_j2u_imply_bit_to_j2u(a, b, a); +} + + +/** + * Calculate the bitwise NAND of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This flips the specified bit and sets the rest + * + * @param a The left-hand integer + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + * @param res Output parameter for the result + */ +inline void +libj2_j2u_nand_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res) +{ + if (b >= LIBJ2_J2U_BIT) { + res->high = UINTMAX_MAX; + res->low = UINTMAX_MAX; + } else if (b >= LIBJ2_JU_BIT) { + res->high = a->high ^ UINTMAX_MAX; + res->high |= ~((uintmax_t)1 << (b - LIBJ2_JU_BIT)); + res->low = UINTMAX_MAX; + } else { + res->high = UINTMAX_MAX; + res->low = a->low ^ UINTMAX_MAX; + res->low |= ~((uintmax_t)1 << b); + } +} + + +/** + * Calculate the bitwise NAND of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This flips the specified bit and sets the rest + * + * @param a The left-hand integer, also used as the + * output parameter for the result + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + */ +inline void +libj2_j2u_nand_bit(struct libj2_j2u *a, unsigned b) +{ + libj2_j2u_nand_bit_to_j2u(a, b, a); +} + + +/** + * Calculate the bitwise NOR of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This clears the specified bit and flips the rest + * + * @param a The left-hand integer + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + * @param res Output parameter for the result + */ +inline void +libj2_j2u_nor_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res) +{ + res->high = a->high ^ UINTMAX_MAX; + res->low = a->low ^ UINTMAX_MAX; + if (b >= LIBJ2_JU_BIT) { + if (b >= LIBJ2_J2U_BIT) + return; + res->high &= ~((uintmax_t)1 << (b - LIBJ2_JU_BIT)); + } else { + res->low &= ~((uintmax_t)1 << b); + } +} + + +/** + * Calculate the bitwise NOR of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This clears the specified bit and flips the rest + * + * @param a The left-hand integer, also used as the + * output parameter for the result + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + */ +inline void +libj2_j2u_nor_bit(struct libj2_j2u *a, unsigned b) +{ + libj2_j2u_nor_bit_to_j2u(a, b, a); +} + + +/** + * Calculate the bitwise XNOR of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This flips all but the specified bit + * + * @param a The left-hand integer + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + * @param res Output parameter for the result + */ +inline void +libj2_j2u_xnor_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res) +{ + res->high = a->high ^ UINTMAX_MAX; + res->low = a->low ^ UINTMAX_MAX; + if (b >= LIBJ2_JU_BIT) { + if (b >= LIBJ2_J2U_BIT) + return; + res->high ^= (uintmax_t)1 << (b - LIBJ2_JU_BIT); + } else { + res->low ^= (uintmax_t)1 << b; + } +} + + +/** + * Calculate the bitwise XNOR of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This flips all but the specified bit + * + * @param a The left-hand integer, also used as the + * output parameter for the result + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + */ +inline void +libj2_j2u_xnor_bit(struct libj2_j2u *a, unsigned b) +{ + libj2_j2u_xnor_bit_to_j2u(a, b, a); +} + + +/** + * Calculate the bitwise NIF of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This flips the specified bit and clears the rest + * + * @param a The left-hand integer + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + * @param res Output parameter for the result + */ +inline void +libj2_j2u_nif_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res) +{ + if (b >= LIBJ2_J2U_BIT) { + res->high = 0; + res->low = 0; + } else if (b >= LIBJ2_JU_BIT) { + res->high = a->high & ((uintmax_t)1 << (b - LIBJ2_JU_BIT)); + res->high ^= (uintmax_t)1 << (b - LIBJ2_JU_BIT); + res->low = 0; + } else { + res->high = 0; + res->low = a->low & ((uintmax_t)1 << b); + res->low ^= (uintmax_t)1 << b; + } +} + + +/** + * Calculate the bitwise NIF of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This flips the specified bit and clears the rest + * + * @param a The left-hand integer, also used as the + * output parameter for the result + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + */ +inline void +libj2_j2u_nif_bit(struct libj2_j2u *a, unsigned b) +{ + libj2_j2u_nif_bit_to_j2u(a, b, a); +} + + +/** + * Calculate the bitwise NIMPLY of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This clears the specified bit + * + * @param a The left-hand integer + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + * @param res Output parameter for the result + */ +inline void +libj2_j2u_nimply_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res) +{ + if (b >= LIBJ2_J2U_BIT) { + res->high = a->high; + res->low = a->low; + } else if (b >= LIBJ2_JU_BIT) { + res->high = a->high & ~((uintmax_t)1 << (b - LIBJ2_JU_BIT)); + res->low = a->low; + } else { + res->high = a->high; + res->low = a->low & ~((uintmax_t)1 << b); + } +} + + +/** + * Calculate the bitwise NIMPLY of an unsigned double-max + * precision integer (left-hand) and unsigned double-max + * precision integer with one specified bit set and the + * reset cleared (right-hand) + * + * This clears the specified bit + * + * @param a The left-hand integer, also used as the + * output parameter for the result + * @param b The index of bit that shall be set in + * the right-hand integer, 0 for the least + * significant bit + */ +inline void +libj2_j2u_nimply_bit(struct libj2_j2u *a, unsigned b) +{ + if (b >= LIBJ2_JU_BIT) { + if (b >= LIBJ2_J2U_BIT) + return; + a->high &= ~((uintmax_t)1 << (b - LIBJ2_JU_BIT)); + } else { + a->low &= ~((uintmax_t)1 << b); + } +} + + +/** + * Check that all of some specified bits are set + * in an unsigned double-max precision integer + * + * `libj2_j2u_has_j2u(a, b)` implements `(*a & *b) == *b` + * + * @param a The integer to inspect + * @param b Integer whose set bits should also be set in `a` + * @return 1 if the set bits in `b` are also set in `a`, + * 0 otherwise + */ +LIBJ2_PURE_ inline int +libj2_j2u_has_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) +{ + return (a->low & b->low) == b->low && (a->high & b->high) == b->high; +} + + +/** + * Check that all of some specified bits are set + * in an unsigned double-max precision integer + * + * `libj2_j2u_has_ju(a, b)` implements `(*a & b) == b` + * + * @param a The integer to inspect + * @param b Integer whose set bits should also be set in `a` + * @return 1 if the set bits in `b` are also set in `a`, + * 0 otherwise + */ +LIBJ2_PURE_ inline int +libj2_j2u_has_ju(const struct libj2_j2u *a, uintmax_t b) +{ + return (a->low & b) == b; +} + + +/** + * Check that all of some specified bits are set + * in the most significant half of an unsigned + * double-max precision integer + * + * `libj2_j2u_has_ju(a, b)` implements `(a->high & b) == b` + * + * @param a The integer to inspect + * @param b Integer whose set bits should also be set in `a`'s + * most significant half (`a->high`) + * @return 1 if the set bits in `b` are also set in `a->high`, + * 0 otherwise + */ +LIBJ2_PURE_ inline int +libj2_j2u_has_high_ju(const struct libj2_j2u *a, uintmax_t b) +{ + return (a->high & b) == b; +} diff --git a/libj2/constants.h b/libj2/constants.h index e33fbff..a13eeac 100644 --- a/libj2/constants.h +++ b/libj2/constants.h @@ -13,7 +13,7 @@ * @param a The integer to inspect * @return 1 if `a` has the value 0, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_is_zero(const struct libj2_j2u *a) { return !a->high && !a->low; @@ -41,7 +41,7 @@ libj2_j2u_zero(struct libj2_j2u *res) * @param a The integer to inspect * @return 1 if `a` has highest representable value, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_is_max(const struct libj2_j2u *a) { return a->high == UINTMAX_MAX && a->low == UINTMAX_MAX; @@ -71,7 +71,7 @@ libj2_j2u_max(struct libj2_j2u *res) * @param a The integer to inspect * @return 1 if `a` has lowest representable value, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_is_min(const struct libj2_j2u *a) { return libj2_j2u_is_zero(a); diff --git a/libj2/division.h b/libj2/division.h index 9607b1b..9797f4e 100644 --- a/libj2/division.h +++ b/libj2/division.h @@ -38,7 +38,9 @@ libj2_j2u_divmod_j2u_to_j2u(struct libj2_j2u *a, const struct libj2_j2u *b, stru goto out; } - /* TODO e = leading_zeroes(a) - leading_zeroes(b) + 1 */ +#if defined(LIBJ2_USE_GCC_INTRINSIC_FUNCTIONS_) + e = libj2_clz_j2u(b) - libj2_clz_j2u(a) + 1U; +#endif while (!libj2_j2u_is_zero(a) && e--) { if (libj2_j2u_lsh_to_j2u_overflow(&d, e, &c)) diff --git a/libj2/signum.h b/libj2/signum.h index 7ae1833..cfd047d 100644 --- a/libj2/signum.h +++ b/libj2/signum.h @@ -13,7 +13,7 @@ * @param a The integer to inspect * @return 1 if `a` has a positive value, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_is_positive(const struct libj2_j2u *a) { return a->high || a->low; @@ -35,7 +35,7 @@ libj2_j2u_is_positive(const struct libj2_j2u *a) * +1 if `a` is positive, and * 0 if `a` is 0 */ -inline int +LIBJ2_PURE_ inline int libj2_sgn_j2u(const struct libj2_j2u *a) { return libj2_j2u_is_positive(a); diff --git a/libj2/unsigned-comparsion.h b/libj2/unsigned-comparsion.h index 3362753..fcc81c9 100644 --- a/libj2/unsigned-comparsion.h +++ b/libj2/unsigned-comparsion.h @@ -15,7 +15,7 @@ * @param b The right-hand value * @return 1 if `*a` is less than `*b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_lt_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) { return a->high < b->high || (a->high == b->high && a->low < b->low); @@ -32,7 +32,7 @@ libj2_j2u_lt_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) * @param b The right-hand value * @return 1 if `*a` is less than or equal to `*b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_le_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) { return a->high < b->high || (a->high == b->high && a->low <= b->low); @@ -49,7 +49,7 @@ libj2_j2u_le_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) * @param b The right-hand value * @return 1 if `*a` is greater than `*b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_gt_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) { return a->high > b->high || (a->high == b->high && a->low > b->low); @@ -66,7 +66,7 @@ libj2_j2u_gt_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) * @param b The right-hand value * @return 1 if `*a` is greater than or equal to `*b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_ge_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) { return a->high > b->high || (a->high == b->high && a->low >= b->low); @@ -83,7 +83,7 @@ libj2_j2u_ge_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) * @param b The right-hand value * @return 1 if `*a` is equal to `*b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_eq_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) { return a->high == b->high && a->low == b->low; @@ -100,7 +100,7 @@ libj2_j2u_eq_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) * @param b The right-hand value * @return 1 if `*a` is not equal to `*b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_ne_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) { return a->high != b->high || a->low != b->low; @@ -120,7 +120,7 @@ libj2_j2u_ne_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) * +1 if `*a` is greater than `*b`, * 0 if `*a` is equal to `*b` */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_cmp_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) { return a->high < b->high ? -1 : a->high > b->high ? +1 : a->low < b->low ? -1 : a->low > b->low; @@ -137,7 +137,7 @@ libj2_j2u_cmp_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b) * @param b The right-hand value * @return 1 if `*a` is less than `b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_lt_ju(const struct libj2_j2u *a, uintmax_t b) { return !a->high && a->low < b; @@ -154,7 +154,7 @@ libj2_j2u_lt_ju(const struct libj2_j2u *a, uintmax_t b) * @param b The right-hand value * @return 1 if `*a` is less than or equal to `b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_le_ju(const struct libj2_j2u *a, uintmax_t b) { return !a->high && a->low <= b; @@ -171,7 +171,7 @@ libj2_j2u_le_ju(const struct libj2_j2u *a, uintmax_t b) * @param b The right-hand value * @return 1 if `*a` is less than `b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_gt_ju(const struct libj2_j2u *a, uintmax_t b) { return a->high || a->low > b; @@ -188,7 +188,7 @@ libj2_j2u_gt_ju(const struct libj2_j2u *a, uintmax_t b) * @param b The right-hand value * @return 1 if `*a` is greater than or equal to `b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_ge_ju(const struct libj2_j2u *a, uintmax_t b) { return a->high || a->low >= b; @@ -205,7 +205,7 @@ libj2_j2u_ge_ju(const struct libj2_j2u *a, uintmax_t b) * @param b The right-hand value * @return 1 if `*a` is equal to `b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_eq_ju(const struct libj2_j2u *a, uintmax_t b) { return !a->high && a->low == b; @@ -222,7 +222,7 @@ libj2_j2u_eq_ju(const struct libj2_j2u *a, uintmax_t b) * @param b The right-hand value * @return 1 if `*a` is not equal to `b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_ne_ju(const struct libj2_j2u *a, uintmax_t b) { return a->high || a->low != b; @@ -242,7 +242,7 @@ libj2_j2u_ne_ju(const struct libj2_j2u *a, uintmax_t b) * +1 if `*a` is greater than `b`, * 0 if `*a` is equal to `b` */ -inline int +LIBJ2_PURE_ inline int libj2_j2u_cmp_ju(const struct libj2_j2u *a, uintmax_t b) { return a->high ? +1 : a->low < b ? -1 : a->low > b; @@ -259,7 +259,7 @@ libj2_j2u_cmp_ju(const struct libj2_j2u *a, uintmax_t b) * @param b The right-hand value * @return 1 if `a` is less than `*b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_ju_lt_j2u(uintmax_t a, const struct libj2_j2u *b) { return libj2_j2u_gt_ju(b, a); @@ -276,7 +276,7 @@ libj2_ju_lt_j2u(uintmax_t a, const struct libj2_j2u *b) * @param b The right-hand value * @return 1 if `a` is less than or equal to `*b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_ju_le_j2u(uintmax_t a, const struct libj2_j2u *b) { return libj2_j2u_ge_ju(b, a); @@ -293,7 +293,7 @@ libj2_ju_le_j2u(uintmax_t a, const struct libj2_j2u *b) * @param b The right-hand value * @return 1 if `a` is less than `*b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_ju_gt_j2u(uintmax_t a, const struct libj2_j2u *b) { return libj2_j2u_lt_ju(b, a); @@ -310,7 +310,7 @@ libj2_ju_gt_j2u(uintmax_t a, const struct libj2_j2u *b) * @param b The right-hand value * @return 1 if `a` is greater than or equal to `*b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_ju_ge_j2u(uintmax_t a, const struct libj2_j2u *b) { return libj2_j2u_le_ju(b, a); @@ -327,7 +327,7 @@ libj2_ju_ge_j2u(uintmax_t a, const struct libj2_j2u *b) * @param b The right-hand value * @return 1 if `a` is equal to `*b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_ju_eq_j2u(uintmax_t a, const struct libj2_j2u *b) { return libj2_j2u_eq_ju(b, a); @@ -344,7 +344,7 @@ libj2_ju_eq_j2u(uintmax_t a, const struct libj2_j2u *b) * @param b The right-hand value * @return 1 if `a` is not equal to `*b`, 0 otherwise */ -inline int +LIBJ2_PURE_ inline int libj2_ju_ne_j2u(uintmax_t a, const struct libj2_j2u *b) { return libj2_j2u_ne_ju(b, a); @@ -364,7 +364,7 @@ libj2_ju_ne_j2u(uintmax_t a, const struct libj2_j2u *b) * +1 if `a` is greater than `*b`, * 0 if `a` is equal to `*b` */ -inline int +LIBJ2_PURE_ inline int libj2_ju_cmp_j2u(uintmax_t a, const struct libj2_j2u *b) { return b->high ? -1 : a < b->low ? -1 : a > b->low; @@ -606,7 +606,7 @@ libj2_vmax_j2u_return(const struct libj2_j2u *a, va_list args) * @return One of the `const struct libj2_j2u *` that as the * maximum of the values of each argument */ -inline const struct libj2_j2u * +LIBJ2_PURE_ inline const struct libj2_j2u * libj2_max_j2u_return(const struct libj2_j2u *a, ... /*, NULL */) { va_list args; @@ -724,7 +724,7 @@ libj2_vmin_j2u_return(const struct libj2_j2u *a, va_list args) * @return One of the `const struct libj2_j2u *` that as the * minimum of the values of each argument */ -inline const struct libj2_j2u * +LIBJ2_PURE_ inline const struct libj2_j2u * libj2_min_j2u_return(const struct libj2_j2u *a, ... /*, NULL */) { va_list args; diff --git a/libj2_cfs_j2u.c b/libj2_cfs_j2u.c new file mode 100644 index 0000000..c2434e0 --- /dev/null +++ b/libj2_cfs_j2u.c @@ -0,0 +1,116 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_cfs_j2u(struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +static void +cfs(const struct libj2_j2u *a, struct libj2_j2u *res) +{ + struct libj2_j2u a_saved = *a, r, b; + + *res = (struct libj2_j2u){111, 222}; + libj2_cfs_j2u_to_j2u(a, res); + EXPECT(libj2_j2u_eq_j2u(a, &a_saved)); + + r = *a; + libj2_cfs_j2u_to_j2u(&r, &r); + EXPECT(libj2_j2u_eq_j2u(&r, res)); + + r = *a; + libj2_cfs_j2u(&r); + EXPECT(libj2_j2u_eq_j2u(&r, res)); + + r = (struct libj2_j2u){111, 222}; + libj2_not_j2u_to_j2u(a, &b); + libj2_sfc_j2u_to_j2u((const struct libj2_j2u *)&b, &r); + libj2_not_j2u(&b); + libj2_not_j2u(&r); + EXPECT(libj2_j2u_eq_j2u(&b, &a_saved)); + EXPECT(libj2_j2u_eq_j2u(&r, res)); + + r = *a; + libj2_not_j2u(&r); + libj2_sfc_j2u_to_j2u(&r, &r); + libj2_not_j2u(&r); + EXPECT(libj2_j2u_eq_j2u(&r, res)); + + r = *a; + libj2_not_j2u(&r); + libj2_sfc_j2u(&r); + libj2_not_j2u(&r); + EXPECT(libj2_j2u_eq_j2u(&r, res)); + + b = (struct libj2_j2u){333, 444}; + libj2_kfs_j2u_to_j2u(a, &b); + EXPECT(libj2_j2u_eq_j2u(a, &a_saved)); + libj2_j2u_sub_j2u_to_j2u(a, &b, &r); + EXPECT(libj2_j2u_eq_j2u(a, &a_saved)); + EXPECT(libj2_j2u_eq_j2u(&r, res)); + + r = *a; + libj2_kfs_j2u(&r); + EXPECT(libj2_j2u_eq_j2u(a, &a_saved)); + EXPECT(libj2_j2u_eq_j2u(&r, &b)); +} + + +int +main(void) +{ + struct libj2_j2u a, r, t; + unsigned i, j; + + libj2_j2u_max(&a); + for (i = 0; i < LIBJ2_J2U_BIT; i++) { + cfs(&a, &r); + libj2_j2u_lsh_to_j2u(&a, 1, &a); + EXPECT(libj2_j2u_eq_j2u(&r, &a)); + } + EXPECT(libj2_j2u_is_zero(&a)); + cfs(&a, &r); + EXPECT(libj2_j2u_is_zero(&r)); + + libj2_j2u_max(&a); + a.high = 0; + for (i = 0; i < LIBJ2_JU_BIT; i++) { + cfs(&a, &r); + libj2_j2u_lsh_to_j2u(&a, 1, &a); + a.high = 0; + EXPECT(libj2_j2u_eq_j2u(&r, &a)); + } + EXPECT(libj2_j2u_is_zero(&a)); + + for (j = 1; j <= 3; j++) { + for (i = 0; i < 256; i++) { + a.high = (j & 1) ? random_ju() : 0; + a.low = (j & 2) ? random_ju() : 0; + while (!libj2_j2u_is_zero(&a)) { + cfs(&a, &r); + libj2_j2u_sub_ju_to_j2u(&a, 1, &t); + libj2_j2u_and_j2u(&a, &t); + EXPECT(libj2_j2u_eq_j2u(&r, &a)); + } + } + } + + return 0; +} + +#endif diff --git a/libj2_cfs_j2u_to_j2u.c b/libj2_cfs_j2u_to_j2u.c new file mode 100644 index 0000000..2e0a11e --- /dev/null +++ b/libj2_cfs_j2u_to_j2u.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_cfs_j2u_to_j2u(const struct libj2_j2u *a, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_cfs_j2u.c */ + +#endif diff --git a/libj2_clo_j2u.c b/libj2_clo_j2u.c new file mode 100644 index 0000000..8fa0d03 --- /dev/null +++ b/libj2_clo_j2u.c @@ -0,0 +1,64 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline unsigned libj2_clo_j2u(const struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +int +main(void) +{ + struct libj2_j2u a, a_saved, t; + unsigned i, j; + + srand((unsigned)time(NULL)); + + for (i = 0; i <= LIBJ2_J2U_BIT; i++) { + for (j = 0; j < 64; j++) { + a.high = random_ju(); + a.low = random_ju(); + libj2_j2u_nimply_bit(&a, LIBJ2_J2U_BIT - 1U); + libj2_j2u_rsh(&a, i); + libj2_j2u_max(&t); + libj2_j2u_lsh(&t, LIBJ2_J2U_BIT - i); + libj2_j2u_or_j2u(&a, &t); + a_saved = a; + + EXPECT(libj2_clo_j2u(&a) == i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + if (i <= LIBJ2_JU_BIT) { + a.low = 0; + a_saved.low = 0; + EXPECT(libj2_clo_j2u(&a) == i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + + if (i < LIBJ2_JU_BIT) { + a.low = UINTMAX_MAX; + a_saved.low = UINTMAX_MAX; + EXPECT(libj2_clo_j2u(&a) == i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + } + } + + return 0; +} + +#endif diff --git a/libj2_cls_j2u.c b/libj2_cls_j2u.c new file mode 100644 index 0000000..78d5033 --- /dev/null +++ b/libj2_cls_j2u.c @@ -0,0 +1,119 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_cls_j2u(struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +static void +cls(const struct libj2_j2u *a, struct libj2_j2u *res) +{ + struct libj2_j2u a_saved = *a, r, b; + + *res = (struct libj2_j2u){111, 222}; + libj2_cls_j2u_to_j2u(a, res); + EXPECT(libj2_j2u_eq_j2u(a, &a_saved)); + + r = *a; + libj2_cls_j2u_to_j2u(&r, &r); + EXPECT(libj2_j2u_eq_j2u(&r, res)); + + r = *a; + libj2_cls_j2u(&r); + EXPECT(libj2_j2u_eq_j2u(&r, res)); + + r = (struct libj2_j2u){111, 222}; + libj2_not_j2u_to_j2u(a, &b); + libj2_slc_j2u_to_j2u((const struct libj2_j2u *)&b, &r); + libj2_not_j2u(&b); + libj2_not_j2u(&r); + EXPECT(libj2_j2u_eq_j2u(&b, &a_saved)); + EXPECT(libj2_j2u_eq_j2u(&r, res)); + + r = *a; + libj2_not_j2u(&r); + libj2_slc_j2u_to_j2u(&r, &r); + libj2_not_j2u(&r); + EXPECT(libj2_j2u_eq_j2u(&r, res)); + + r = *a; + libj2_not_j2u(&r); + libj2_slc_j2u(&r); + libj2_not_j2u(&r); + EXPECT(libj2_j2u_eq_j2u(&r, res)); + + b = (struct libj2_j2u){333, 444}; + libj2_kls_j2u_to_j2u(a, &b); + EXPECT(libj2_j2u_eq_j2u(a, &a_saved)); + libj2_j2u_sub_j2u_to_j2u(a, &b, &r); + EXPECT(libj2_j2u_eq_j2u(a, &a_saved)); + EXPECT(libj2_j2u_eq_j2u(&r, res)); + + r = *a; + libj2_kls_j2u(&r); + EXPECT(libj2_j2u_eq_j2u(a, &a_saved)); + EXPECT(libj2_j2u_eq_j2u(&r, &b)); +} + + +int +main(void) +{ + struct libj2_j2u a, r; + unsigned i, j, bit; + + libj2_j2u_max(&a); + for (i = 0; i < LIBJ2_J2U_BIT; i++) { + cls(&a, &r); + libj2_j2u_rsh_to_j2u(&a, 1, &a); + EXPECT(libj2_j2u_eq_j2u(&r, &a)); + } + EXPECT(libj2_j2u_is_zero(&a)); + cls(&a, &r); + EXPECT(libj2_j2u_is_zero(&r)); + + libj2_j2u_max(&a); + a.low = 0; + for (i = 0; i < LIBJ2_JU_BIT; i++) { + cls(&a, &r); + libj2_j2u_rsh_to_j2u(&a, 1, &a); + a.low = 0; + EXPECT(libj2_j2u_eq_j2u(&r, &a)); + } + EXPECT(libj2_j2u_is_zero(&a)); + + for (j = 1; j <= 3; j++) { + for (i = 0; i < 256; i++) { + a.high = (j & 1) ? random_ju() : 0; + a.low = (j & 2) ? random_ju() : 0; + while (!libj2_j2u_is_zero(&a)) { + cls(&a, &r); + bit = libj2_fls_j2u(&a); + EXPECT(bit); + bit -= 1U; + EXPECT(libj2_j2u_test_bit(&a, bit)); + libj2_j2u_xor_bit(&a, bit); + EXPECT(libj2_j2u_eq_j2u(&r, &a)); + } + } + } + + return 0; +} + +#endif diff --git a/libj2_cls_j2u_to_j2u.c b/libj2_cls_j2u_to_j2u.c new file mode 100644 index 0000000..2a8eca9 --- /dev/null +++ b/libj2_cls_j2u_to_j2u.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_cls_j2u_to_j2u(const struct libj2_j2u *a, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_cls_j2u.c */ + +#endif diff --git a/libj2_clz_j2u.c b/libj2_clz_j2u.c new file mode 100644 index 0000000..5e6f1f4 --- /dev/null +++ b/libj2_clz_j2u.c @@ -0,0 +1,61 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline unsigned libj2_clz_j2u(const struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +int +main(void) +{ + struct libj2_j2u a, a_saved; + unsigned i, j; + + srand((unsigned)time(NULL)); + + for (i = 0; i <= LIBJ2_J2U_BIT; i++) { + for (j = 0; j < 64; j++) { + a.high = random_ju(); + a.low = random_ju(); + libj2_j2u_or_bit(&a, LIBJ2_J2U_BIT - 1U); + libj2_j2u_rsh(&a, i); + a_saved = a; + + EXPECT(libj2_clz_j2u(&a) == i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + if (i <= LIBJ2_JU_BIT) { + a.low = UINTMAX_MAX; + a_saved.low = UINTMAX_MAX; + EXPECT(libj2_clz_j2u(&a) == i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + + if (i < LIBJ2_JU_BIT) { + a.low = 0; + a_saved.low = 0; + EXPECT(libj2_clz_j2u(&a) == i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + } + } + + return 0; +} + +#endif diff --git a/libj2_co_j2u.c b/libj2_co_j2u.c new file mode 100644 index 0000000..6b1988a --- /dev/null +++ b/libj2_co_j2u.c @@ -0,0 +1,95 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline unsigned libj2_co_j2u(const struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(unsigned *popcount) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + *popcount = 0; + while (n--) { + if (rand() < rand()) { + r |= (uintmax_t)1 << n; + *popcount += 1U; + } + } + return r; +} + + +int +main(void) +{ + struct libj2_j2u a; + uintmax_t high, low; + unsigned i, high_n, low_n; + + srand((unsigned)time(NULL)); + + a.high = 0; + a.low = 0; + EXPECT(libj2_co_j2u(&a) == 0); + EXPECT(a.high == 0); + EXPECT(a.low == 0); + + a.high = 0; + a.low = UINTMAX_MAX; + EXPECT(libj2_co_j2u(&a) == LIBJ2_JU_BIT); + EXPECT(a.high == 0); + EXPECT(a.low == UINTMAX_MAX); + + a.high = UINTMAX_MAX; + a.low = 0; + EXPECT(libj2_co_j2u(&a) == LIBJ2_JU_BIT); + EXPECT(a.high == UINTMAX_MAX); + EXPECT(a.low == 0); + + a.high = UINTMAX_MAX; + a.low = UINTMAX_MAX; + EXPECT(libj2_co_j2u(&a) == LIBJ2_J2U_BIT); + EXPECT(a.high == UINTMAX_MAX); + EXPECT(a.low == UINTMAX_MAX); + + for (i = 0; i < 256; i++) { + a.high = high = random_ju(&high_n); + a.low = low = random_ju(&low_n); + EXPECT(libj2_co_j2u(&a) == high_n + low_n); + EXPECT(a.high == high); + EXPECT(a.low == low); + + a.high = high = random_ju(&high_n); + a.low = low = 0; + EXPECT(libj2_co_j2u(&a) == high_n); + EXPECT(a.high == high); + EXPECT(a.low == 0); + + a.high = high = random_ju(&high_n); + a.low = low = UINTMAX_MAX; + EXPECT(libj2_co_j2u(&a) == high_n + LIBJ2_JU_BIT); + EXPECT(a.high == high); + EXPECT(a.low == UINTMAX_MAX); + + a.high = high = 0; + a.low = low = random_ju(&low_n); + EXPECT(libj2_co_j2u(&a) == low_n); + EXPECT(a.high == 0); + EXPECT(a.low == low); + + a.high = high = UINTMAX_MAX; + a.low = low = random_ju(&low_n); + EXPECT(libj2_co_j2u(&a) == LIBJ2_JU_BIT + low_n); + EXPECT(a.high == UINTMAX_MAX); + EXPECT(a.low == low); + } + + return 0; +} + +#endif diff --git a/libj2_cto_j2u.c b/libj2_cto_j2u.c new file mode 100644 index 0000000..17ea8b6 --- /dev/null +++ b/libj2_cto_j2u.c @@ -0,0 +1,62 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline unsigned libj2_cto_j2u(const struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +int +main(void) +{ + struct libj2_j2u a, a_saved; + unsigned i, j; + + srand((unsigned)time(NULL)); + + for (i = 0; i <= LIBJ2_J2U_BIT; i++) { + for (j = 0; j < 64; j++) { + a.high = random_ju(); + a.low = random_ju(); + libj2_j2u_or_bit(&a, 0); + libj2_j2u_lsh(&a, i); + libj2_j2u_sub_ju(&a, 1); + a_saved = a; + + EXPECT(libj2_cto_j2u(&a) == i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + if (i <= LIBJ2_JU_BIT) { + a.high = 0; + a_saved.high = 0; + EXPECT(libj2_cto_j2u(&a) == i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + + if (i < LIBJ2_JU_BIT) { + a.high = UINTMAX_MAX; + a_saved.high = UINTMAX_MAX; + EXPECT(libj2_cto_j2u(&a) == i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + } + } + + return 0; +} + +#endif diff --git a/libj2_ctz_j2u.c b/libj2_ctz_j2u.c new file mode 100644 index 0000000..3c4ff87 --- /dev/null +++ b/libj2_ctz_j2u.c @@ -0,0 +1,61 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline unsigned libj2_ctz_j2u(const struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +int +main(void) +{ + struct libj2_j2u a, a_saved; + unsigned i, j; + + srand((unsigned)time(NULL)); + + for (i = 0; i <= LIBJ2_J2U_BIT; i++) { + for (j = 0; j < 64; j++) { + a.high = random_ju(); + a.low = random_ju(); + libj2_j2u_or_bit(&a, 0); + libj2_j2u_lsh(&a, i); + a_saved = a; + + EXPECT(libj2_ctz_j2u(&a) == i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + if (i <= LIBJ2_JU_BIT) { + a.high = UINTMAX_MAX; + a_saved.high = UINTMAX_MAX; + EXPECT(libj2_ctz_j2u(&a) == i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + + if (i < LIBJ2_JU_BIT) { + a.high = 0; + a_saved.high = 0; + EXPECT(libj2_ctz_j2u(&a) == i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + } + } + + return 0; +} + +#endif diff --git a/libj2_cz_j2u.c b/libj2_cz_j2u.c new file mode 100644 index 0000000..60da659 --- /dev/null +++ b/libj2_cz_j2u.c @@ -0,0 +1,95 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline unsigned libj2_cz_j2u(const struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(unsigned *popcount) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + *popcount = 0; + while (n--) { + if (rand() < rand()) { + r |= (uintmax_t)1 << n; + *popcount += 1U; + } + } + return r; +} + + +int +main(void) +{ + struct libj2_j2u a; + uintmax_t high, low; + unsigned i, high_n, low_n; + + srand((unsigned)time(NULL)); + + a.high = 0; + a.low = 0; + EXPECT(libj2_cz_j2u(&a) == LIBJ2_J2U_BIT); + EXPECT(a.high == 0); + EXPECT(a.low == 0); + + a.high = 0; + a.low = UINTMAX_MAX; + EXPECT(libj2_cz_j2u(&a) == LIBJ2_JU_BIT); + EXPECT(a.high == 0); + EXPECT(a.low == UINTMAX_MAX); + + a.high = UINTMAX_MAX; + a.low = 0; + EXPECT(libj2_cz_j2u(&a) == LIBJ2_JU_BIT); + EXPECT(a.high == UINTMAX_MAX); + EXPECT(a.low == 0); + + a.high = UINTMAX_MAX; + a.low = UINTMAX_MAX; + EXPECT(libj2_cz_j2u(&a) == 0); + EXPECT(a.high == UINTMAX_MAX); + EXPECT(a.low == UINTMAX_MAX); + + for (i = 0; i < 256; i++) { + a.high = high = ~random_ju(&high_n); + a.low = low = ~random_ju(&low_n); + EXPECT(libj2_cz_j2u(&a) == high_n + low_n); + EXPECT(a.high == high); + EXPECT(a.low == low); + + a.high = high = ~random_ju(&high_n); + a.low = low = 0; + EXPECT(libj2_cz_j2u(&a) == high_n + LIBJ2_JU_BIT); + EXPECT(a.high == high); + EXPECT(a.low == 0); + + a.high = high = ~random_ju(&high_n); + a.low = low = UINTMAX_MAX; + EXPECT(libj2_cz_j2u(&a) == high_n); + EXPECT(a.high == high); + EXPECT(a.low == UINTMAX_MAX); + + a.high = high = 0; + a.low = low = ~random_ju(&low_n); + EXPECT(libj2_cz_j2u(&a) == LIBJ2_JU_BIT + low_n); + EXPECT(a.high == 0); + EXPECT(a.low == low); + + a.high = high = UINTMAX_MAX; + a.low = low = ~random_ju(&low_n); + EXPECT(libj2_cz_j2u(&a) == low_n); + EXPECT(a.high == UINTMAX_MAX); + EXPECT(a.low == low); + } + + return 0; +} + +#endif diff --git a/libj2_ffc_j2u.c b/libj2_ffc_j2u.c new file mode 100644 index 0000000..5d2c481 --- /dev/null +++ b/libj2_ffc_j2u.c @@ -0,0 +1,125 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline unsigned libj2_ffc_j2u(const struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +int +main(void) +{ + struct libj2_j2u a, b, a_saved, b_saved; + unsigned i, j; + + srand((unsigned)time(NULL)); + + libj2_ju_to_j2u(0, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_ffc_j2u(&a) == 0); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(1, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_ffc_j2u(&a) == 1); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(2, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_ffc_j2u(&a) == 2); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(3, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_ffc_j2u(&a) == 1); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(4, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_ffc_j2u(&a) == 3); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(5, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_ffc_j2u(&a) == 1); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(6, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_ffc_j2u(&a) == 2); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_j2u_max(&a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_ffc_j2u(&a) == 1); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + for (i = 0; i < LIBJ2_J2U_BIT; i++) { + libj2_j2u_zero(&a); + libj2_j2u_or_bit(&a, i); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_ffc_j2u(&a) == i + 1U); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + + for (i = 0; i < LIBJ2_JU_BIT; i++) { + libj2_j2u_zero(&a); + libj2_j2u_or_bit(&a, i); + a.high = UINTMAX_MAX; + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_ffc_j2u(&a) == i + 1U); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + + for (i = 0; i < LIBJ2_J2U_BIT; i++) { + libj2_j2u_max(&a); + libj2_j2u_lsh(&a, i); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_ffc_j2u(&a) == i + 1U); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + libj2_not_j2u(&a); + a_saved = a; + + for (j = 0; j < 32; j++) { + EXPECT(libj2_j2u_test_bit(&a, i)); + b.high = random_ju(); + b.low = random_ju(); + libj2_j2u_and_j2u(&b, &a); + libj2_j2u_or_bit(&b, i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + libj2_not_j2u(&b); + b_saved = b; + EXPECT(libj2_ffc_j2u(&b) == i + 1U); + EXPECT(libj2_j2u_eq_j2u(&b, &b_saved)); + } + } + + return 0; +} + +#endif diff --git a/libj2_ffs_j2u.c b/libj2_ffs_j2u.c new file mode 100644 index 0000000..59b5996 --- /dev/null +++ b/libj2_ffs_j2u.c @@ -0,0 +1,110 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline unsigned libj2_ffs_j2u(const struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +int +main(void) +{ + struct libj2_j2u a, b, a_saved, b_saved; + unsigned i, j; + + srand((unsigned)time(NULL)); + + libj2_ju_to_j2u(0, &a); + a_saved = a; + EXPECT(libj2_ffs_j2u(&a) == 0); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(1, &a); + a_saved = a; + EXPECT(libj2_ffs_j2u(&a) == 1); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(2, &a); + a_saved = a; + EXPECT(libj2_ffs_j2u(&a) == 2); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(3, &a); + a_saved = a; + EXPECT(libj2_ffs_j2u(&a) == 1); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(4, &a); + a_saved = a; + EXPECT(libj2_ffs_j2u(&a) == 3); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(5, &a); + a_saved = a; + EXPECT(libj2_ffs_j2u(&a) == 1); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(6, &a); + a_saved = a; + EXPECT(libj2_ffs_j2u(&a) == 2); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_j2u_max(&a); + EXPECT(libj2_ffs_j2u(&a) == 1); + EXPECT(libj2_j2u_is_max(&a)); + + for (i = 0; i < LIBJ2_J2U_BIT; i++) { + libj2_j2u_zero(&a); + libj2_j2u_or_bit(&a, i); + a_saved = a; + EXPECT(libj2_ffs_j2u(&a) == i + 1U); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + + for (i = 0; i < LIBJ2_JU_BIT; i++) { + libj2_j2u_zero(&a); + libj2_j2u_or_bit(&a, i); + a.high = UINTMAX_MAX; + a_saved = a; + EXPECT(libj2_ffs_j2u(&a) == i + 1U); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + + for (i = 0; i < LIBJ2_J2U_BIT; i++) { + libj2_j2u_max(&a); + libj2_j2u_lsh(&a, i); + a_saved = a; + EXPECT(libj2_ffs_j2u(&a) == i + 1U); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + for (j = 0; j < 32; j++) { + EXPECT(libj2_j2u_test_bit(&a, i)); + b.high = random_ju(); + b.low = random_ju(); + libj2_j2u_and_j2u(&b, &a); + libj2_j2u_or_bit(&b, i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + b_saved = b; + EXPECT(libj2_ffs_j2u(&b) == i + 1U); + EXPECT(libj2_j2u_eq_j2u(&b, &b_saved)); + } + } + + return 0; +} + +#endif diff --git a/libj2_flc_j2u.c b/libj2_flc_j2u.c new file mode 100644 index 0000000..905c350 --- /dev/null +++ b/libj2_flc_j2u.c @@ -0,0 +1,125 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline unsigned libj2_flc_j2u(const struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +int +main(void) +{ + struct libj2_j2u a, b, a_saved, b_saved; + unsigned i, j; + + srand((unsigned)time(NULL)); + + libj2_ju_to_j2u(0, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_flc_j2u(&a) == 0); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(1, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_flc_j2u(&a) == 1); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(2, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_flc_j2u(&a) == 2); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(3, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_flc_j2u(&a) == 2); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(4, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_flc_j2u(&a) == 3); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(5, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_flc_j2u(&a) == 3); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(6, &a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_flc_j2u(&a) == 3); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_j2u_max(&a); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_flc_j2u(&a) == LIBJ2_J2U_BIT); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + for (i = 0; i < LIBJ2_J2U_BIT; i++) { + libj2_j2u_zero(&a); + libj2_j2u_or_bit(&a, i); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_flc_j2u(&a) == i + 1U); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + + for (i = LIBJ2_JU_BIT; i < LIBJ2_J2U_BIT; i++) { + libj2_j2u_zero(&a); + libj2_j2u_or_bit(&a, i); + a.low = UINTMAX_MAX; + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_flc_j2u(&a) == i + 1U); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + + for (i = 0; i < LIBJ2_J2U_BIT; i++) { + libj2_j2u_max(&a); + libj2_j2u_rsh(&a, i); + libj2_not_j2u(&a); + a_saved = a; + EXPECT(libj2_flc_j2u(&a) == LIBJ2_J2U_BIT - i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + libj2_not_j2u(&a); + a_saved = a; + + for (j = 0; j < 32; j++) { + EXPECT(libj2_j2u_test_bit(&a, LIBJ2_J2U_BIT - 1U - i)); + b.high = random_ju(); + b.low = random_ju(); + libj2_j2u_and_j2u(&b, &a); + libj2_j2u_or_bit(&b, LIBJ2_J2U_BIT - 1U - i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + libj2_not_j2u(&b); + b_saved = b; + EXPECT(libj2_flc_j2u(&b) == LIBJ2_J2U_BIT - i); + EXPECT(libj2_j2u_eq_j2u(&b, &b_saved)); + } + } + + return 0; +} + +#endif diff --git a/libj2_fls_j2u.c b/libj2_fls_j2u.c new file mode 100644 index 0000000..fe2d439 --- /dev/null +++ b/libj2_fls_j2u.c @@ -0,0 +1,110 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline unsigned libj2_fls_j2u(const struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +int +main(void) +{ + struct libj2_j2u a, b, a_saved, b_saved; + unsigned i, j; + + srand((unsigned)time(NULL)); + + libj2_ju_to_j2u(0, &a); + a_saved = a; + EXPECT(libj2_fls_j2u(&a) == 0); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(1, &a); + a_saved = a; + EXPECT(libj2_fls_j2u(&a) == 1); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(2, &a); + a_saved = a; + EXPECT(libj2_fls_j2u(&a) == 2); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(3, &a); + a_saved = a; + EXPECT(libj2_fls_j2u(&a) == 2); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(4, &a); + a_saved = a; + EXPECT(libj2_fls_j2u(&a) == 3); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(5, &a); + a_saved = a; + EXPECT(libj2_fls_j2u(&a) == 3); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_ju_to_j2u(6, &a); + a_saved = a; + EXPECT(libj2_fls_j2u(&a) == 3); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + libj2_j2u_max(&a); + EXPECT(libj2_fls_j2u(&a) == LIBJ2_J2U_BIT); + EXPECT(libj2_j2u_is_max(&a)); + + for (i = 0; i < LIBJ2_J2U_BIT; i++) { + libj2_j2u_zero(&a); + libj2_j2u_or_bit(&a, i); + a_saved = a; + EXPECT(libj2_fls_j2u(&a) == i + 1U); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + + for (i = LIBJ2_JU_BIT; i < LIBJ2_J2U_BIT; i++) { + libj2_j2u_zero(&a); + libj2_j2u_or_bit(&a, i); + a.low = UINTMAX_MAX; + a_saved = a; + EXPECT(libj2_fls_j2u(&a) == i + 1U); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + } + + for (i = 0; i < LIBJ2_J2U_BIT; i++) { + libj2_j2u_max(&a); + libj2_j2u_rsh(&a, i); + a_saved = a; + EXPECT(libj2_fls_j2u(&a) == LIBJ2_J2U_BIT - i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + + for (j = 0; j < 32; j++) { + EXPECT(libj2_j2u_test_bit(&a, LIBJ2_J2U_BIT - 1U - i)); + b.high = random_ju(); + b.low = random_ju(); + libj2_j2u_and_j2u(&b, &a); + libj2_j2u_or_bit(&b, LIBJ2_J2U_BIT - 1U - i); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + b_saved = b; + EXPECT(libj2_fls_j2u(&b) == LIBJ2_J2U_BIT - i); + EXPECT(libj2_j2u_eq_j2u(&b, &b_saved)); + } + } + + return 0; +} + +#endif diff --git a/libj2_j2u_and_bit.c b/libj2_j2u_and_bit.c new file mode 100644 index 0000000..502f72d --- /dev/null +++ b/libj2_j2u_and_bit.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_and_bit(struct libj2_j2u *a, unsigned b); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_j2u_and_bit_to_j2u.c */ + +#endif diff --git a/libj2_j2u_and_bit_to_j2u.c b/libj2_j2u_and_bit_to_j2u.c new file mode 100644 index 0000000..0c54279 --- /dev/null +++ b/libj2_j2u_and_bit_to_j2u.c @@ -0,0 +1,72 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_and_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +static void +check(uintmax_t high, uintmax_t low, unsigned shift) +{ + struct libj2_j2u a, r, expected; + + a.high = high; + a.low = low; + + libj2_ju_lsh_to_j2u(1U, shift, &expected); + libj2_j2u_and_j2u_to_j2u(&a, &expected, &expected); + + r = (struct libj2_j2u){111, 222}; + libj2_j2u_and_bit_to_j2u(&a, shift, &r); + EXPECT(a.high == high); + EXPECT(a.low == low); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_and_bit_to_j2u(&r, shift, &r); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_and_bit(&r, shift); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); +} + + +int +main(void) +{ + unsigned i; + + srand((unsigned)time(NULL)); + + for (i = 0; i < LIBJ2_J2U_BIT + 4U; i++) { + check(0, 0, i); + check(0, random_ju(), i); + check(0, UINTMAX_MAX, i); + check(random_ju(), 0, i); + check(random_ju(), random_ju(), i); + check(random_ju(), UINTMAX_MAX, i); + check(UINTMAX_MAX, 0, i); + check(UINTMAX_MAX, random_ju(), i); + check(UINTMAX_MAX, UINTMAX_MAX, i); + } + + return 0; +} + +#endif diff --git a/libj2_j2u_has_high_ju.c b/libj2_j2u_has_high_ju.c new file mode 100644 index 0000000..eb34043 --- /dev/null +++ b/libj2_j2u_has_high_ju.c @@ -0,0 +1,40 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline int libj2_j2u_has_high_ju(const struct libj2_j2u *a, uintmax_t b); +/* TODO Add man page */ + + +#else + +int +main(void) +{ + struct libj2_j2u a; + uintmax_t h, i, j, b; + int expected; + + for (h = 0; h < 10; h++) { + a.low = h; + for (i = 0; i < 128; i++) { + a.high = i; + for (b = 0; b < 128; b++) { + expected = 1; + for (j = 0; j < LIBJ2_JU_BIT; j++) { + if (((b & ~a.high) >> j) & 1U) { + expected = 0; + break; + } + } + EXPECT(libj2_j2u_has_high_ju(&a, b) == expected); + EXPECT(a.low == h); + EXPECT(a.high == i); + } + } + } + + return 0; +} + +#endif diff --git a/libj2_j2u_has_j2u.c b/libj2_j2u_has_j2u.c new file mode 100644 index 0000000..6a1f96d --- /dev/null +++ b/libj2_j2u_has_j2u.c @@ -0,0 +1,36 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline int libj2_j2u_has_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b); +/* TODO Add man page */ + + +#else + +int +main(void) +{ + struct libj2_j2u a, b, a_saved, b_saved; + int expected; + + for (a.high = 0; a.high < 32U; a.high++) { + for (a.low = 0; a.low < 32U; a.low++) { + for (b.high = 0; b.high < 32U; b.high++) { + for (b.low = 0; b.low < 32U; b.low++) { + a_saved = a; + b_saved = b; + expected = libj2_j2u_has_ju(&a, b.low); + expected &= libj2_j2u_has_high_ju(&a, b.high); + EXPECT(libj2_j2u_has_j2u(&a, &b) == expected); + EXPECT(libj2_j2u_eq_j2u(&a, &a_saved)); + EXPECT(libj2_j2u_eq_j2u(&b, &b_saved)); + } + } + } + } + + return 0; +} + +#endif diff --git a/libj2_j2u_has_ju.c b/libj2_j2u_has_ju.c new file mode 100644 index 0000000..b531c50 --- /dev/null +++ b/libj2_j2u_has_ju.c @@ -0,0 +1,40 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline int libj2_j2u_has_ju(const struct libj2_j2u *a, uintmax_t b); +/* TODO Add man page */ + + +#else + +int +main(void) +{ + struct libj2_j2u a; + uintmax_t h, i, j, b; + int expected; + + for (h = 0; h < 10; h++) { + a.high = h; + for (i = 0; i < 128; i++) { + a.low = i; + for (b = 0; b < 128; b++) { + expected = 1; + for (j = 0; j < LIBJ2_JU_BIT; j++) { + if (((b & ~a.low) >> j) & 1U) { + expected = 0; + break; + } + } + EXPECT(libj2_j2u_has_ju(&a, b) == expected); + EXPECT(a.high == h); + EXPECT(a.low == i); + } + } + } + + return 0; +} + +#endif diff --git a/libj2_j2u_if_bit.c b/libj2_j2u_if_bit.c new file mode 100644 index 0000000..1c17b70 --- /dev/null +++ b/libj2_j2u_if_bit.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_if_bit(struct libj2_j2u *a, unsigned b); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_j2u_if_bit_to_j2u.c */ + +#endif diff --git a/libj2_j2u_if_bit_to_j2u.c b/libj2_j2u_if_bit_to_j2u.c new file mode 100644 index 0000000..edd5193 --- /dev/null +++ b/libj2_j2u_if_bit_to_j2u.c @@ -0,0 +1,72 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_if_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +static void +check(uintmax_t high, uintmax_t low, unsigned shift) +{ + struct libj2_j2u a, r, expected; + + a.high = high; + a.low = low; + + libj2_ju_lsh_to_j2u(1U, shift, &expected); + libj2_j2u_if_j2u_to_j2u(&a, &expected, &expected); + + r = (struct libj2_j2u){111, 222}; + libj2_j2u_if_bit_to_j2u(&a, shift, &r); + EXPECT(a.high == high); + EXPECT(a.low == low); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_if_bit_to_j2u(&r, shift, &r); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_if_bit(&r, shift); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); +} + + +int +main(void) +{ + unsigned i; + + srand((unsigned)time(NULL)); + + for (i = 0; i < LIBJ2_J2U_BIT + 4U; i++) { + check(0, 0, i); + check(0, random_ju(), i); + check(0, UINTMAX_MAX, i); + check(random_ju(), 0, i); + check(random_ju(), random_ju(), i); + check(random_ju(), UINTMAX_MAX, i); + check(UINTMAX_MAX, 0, i); + check(UINTMAX_MAX, random_ju(), i); + check(UINTMAX_MAX, UINTMAX_MAX, i); + } + + return 0; +} + +#endif diff --git a/libj2_j2u_imply_bit.c b/libj2_j2u_imply_bit.c new file mode 100644 index 0000000..08191df --- /dev/null +++ b/libj2_j2u_imply_bit.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_imply_bit(struct libj2_j2u *a, unsigned b); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_j2u_imply_bit_to_j2u.c */ + +#endif diff --git a/libj2_j2u_imply_bit_to_j2u.c b/libj2_j2u_imply_bit_to_j2u.c new file mode 100644 index 0000000..7dfc6d4 --- /dev/null +++ b/libj2_j2u_imply_bit_to_j2u.c @@ -0,0 +1,72 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_imply_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +static void +check(uintmax_t high, uintmax_t low, unsigned shift) +{ + struct libj2_j2u a, r, expected; + + a.high = high; + a.low = low; + + libj2_ju_lsh_to_j2u(1U, shift, &expected); + libj2_j2u_imply_j2u_to_j2u(&a, &expected, &expected); + + r = (struct libj2_j2u){111, 222}; + libj2_j2u_imply_bit_to_j2u(&a, shift, &r); + EXPECT(a.high == high); + EXPECT(a.low == low); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_imply_bit_to_j2u(&r, shift, &r); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_imply_bit(&r, shift); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); +} + + +int +main(void) +{ + unsigned i; + + srand((unsigned)time(NULL)); + + for (i = 0; i < LIBJ2_J2U_BIT + 4U; i++) { + check(0, 0, i); + check(0, random_ju(), i); + check(0, UINTMAX_MAX, i); + check(random_ju(), 0, i); + check(random_ju(), random_ju(), i); + check(random_ju(), UINTMAX_MAX, i); + check(UINTMAX_MAX, 0, i); + check(UINTMAX_MAX, random_ju(), i); + check(UINTMAX_MAX, UINTMAX_MAX, i); + } + + return 0; +} + +#endif diff --git a/libj2_j2u_nand_bit.c b/libj2_j2u_nand_bit.c new file mode 100644 index 0000000..d139564 --- /dev/null +++ b/libj2_j2u_nand_bit.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_nand_bit(struct libj2_j2u *a, unsigned b); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_j2u_nand_bit_to_j2u.c */ + +#endif diff --git a/libj2_j2u_nand_bit_to_j2u.c b/libj2_j2u_nand_bit_to_j2u.c new file mode 100644 index 0000000..30488ee --- /dev/null +++ b/libj2_j2u_nand_bit_to_j2u.c @@ -0,0 +1,72 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_nand_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +static void +check(uintmax_t high, uintmax_t low, unsigned shift) +{ + struct libj2_j2u a, r, expected; + + a.high = high; + a.low = low; + + libj2_ju_lsh_to_j2u(1U, shift, &expected); + libj2_j2u_nand_j2u_to_j2u(&a, &expected, &expected); + + r = (struct libj2_j2u){111, 222}; + libj2_j2u_nand_bit_to_j2u(&a, shift, &r); + EXPECT(a.high == high); + EXPECT(a.low == low); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_nand_bit_to_j2u(&r, shift, &r); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_nand_bit(&r, shift); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); +} + + +int +main(void) +{ + unsigned i; + + srand((unsigned)time(NULL)); + + for (i = 0; i < LIBJ2_J2U_BIT + 4U; i++) { + check(0, 0, i); + check(0, random_ju(), i); + check(0, UINTMAX_MAX, i); + check(random_ju(), 0, i); + check(random_ju(), random_ju(), i); + check(random_ju(), UINTMAX_MAX, i); + check(UINTMAX_MAX, 0, i); + check(UINTMAX_MAX, random_ju(), i); + check(UINTMAX_MAX, UINTMAX_MAX, i); + } + + return 0; +} + +#endif diff --git a/libj2_j2u_nif_bit.c b/libj2_j2u_nif_bit.c new file mode 100644 index 0000000..379a051 --- /dev/null +++ b/libj2_j2u_nif_bit.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_nif_bit(struct libj2_j2u *a, unsigned b); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_j2u_nif_bit_to_j2u.c */ + +#endif diff --git a/libj2_j2u_nif_bit_to_j2u.c b/libj2_j2u_nif_bit_to_j2u.c new file mode 100644 index 0000000..f88a54e --- /dev/null +++ b/libj2_j2u_nif_bit_to_j2u.c @@ -0,0 +1,72 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_nif_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +static void +check(uintmax_t high, uintmax_t low, unsigned shift) +{ + struct libj2_j2u a, r, expected; + + a.high = high; + a.low = low; + + libj2_ju_lsh_to_j2u(1U, shift, &expected); + libj2_j2u_nif_j2u_to_j2u(&a, &expected, &expected); + + r = (struct libj2_j2u){111, 222}; + libj2_j2u_nif_bit_to_j2u(&a, shift, &r); + EXPECT(a.high == high); + EXPECT(a.low == low); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_nif_bit_to_j2u(&r, shift, &r); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_nif_bit(&r, shift); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); +} + + +int +main(void) +{ + unsigned i; + + srand((unsigned)time(NULL)); + + for (i = 0; i < LIBJ2_J2U_BIT + 4U; i++) { + check(0, 0, i); + check(0, random_ju(), i); + check(0, UINTMAX_MAX, i); + check(random_ju(), 0, i); + check(random_ju(), random_ju(), i); + check(random_ju(), UINTMAX_MAX, i); + check(UINTMAX_MAX, 0, i); + check(UINTMAX_MAX, random_ju(), i); + check(UINTMAX_MAX, UINTMAX_MAX, i); + } + + return 0; +} + +#endif diff --git a/libj2_j2u_nimply_bit.c b/libj2_j2u_nimply_bit.c new file mode 100644 index 0000000..9ad7acd --- /dev/null +++ b/libj2_j2u_nimply_bit.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_nimply_bit(struct libj2_j2u *a, unsigned b); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_j2u_nimply_bit_to_j2u.c */ + +#endif diff --git a/libj2_j2u_nimply_bit_to_j2u.c b/libj2_j2u_nimply_bit_to_j2u.c new file mode 100644 index 0000000..e7fc922 --- /dev/null +++ b/libj2_j2u_nimply_bit_to_j2u.c @@ -0,0 +1,72 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_nimply_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +static void +check(uintmax_t high, uintmax_t low, unsigned shift) +{ + struct libj2_j2u a, r, expected; + + a.high = high; + a.low = low; + + libj2_ju_lsh_to_j2u(1U, shift, &expected); + libj2_j2u_nimply_j2u_to_j2u(&a, &expected, &expected); + + r = (struct libj2_j2u){111, 222}; + libj2_j2u_nimply_bit_to_j2u(&a, shift, &r); + EXPECT(a.high == high); + EXPECT(a.low == low); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_nimply_bit_to_j2u(&r, shift, &r); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_nimply_bit(&r, shift); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); +} + + +int +main(void) +{ + unsigned i; + + srand((unsigned)time(NULL)); + + for (i = 0; i < LIBJ2_J2U_BIT + 4U; i++) { + check(0, 0, i); + check(0, random_ju(), i); + check(0, UINTMAX_MAX, i); + check(random_ju(), 0, i); + check(random_ju(), random_ju(), i); + check(random_ju(), UINTMAX_MAX, i); + check(UINTMAX_MAX, 0, i); + check(UINTMAX_MAX, random_ju(), i); + check(UINTMAX_MAX, UINTMAX_MAX, i); + } + + return 0; +} + +#endif diff --git a/libj2_j2u_nor_bit.c b/libj2_j2u_nor_bit.c new file mode 100644 index 0000000..e4d6471 --- /dev/null +++ b/libj2_j2u_nor_bit.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_nor_bit(struct libj2_j2u *a, unsigned b); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_j2u_nor_bit_to_j2u.c */ + +#endif diff --git a/libj2_j2u_nor_bit_to_j2u.c b/libj2_j2u_nor_bit_to_j2u.c new file mode 100644 index 0000000..aed8465 --- /dev/null +++ b/libj2_j2u_nor_bit_to_j2u.c @@ -0,0 +1,72 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_nor_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +static void +check(uintmax_t high, uintmax_t low, unsigned shift) +{ + struct libj2_j2u a, r, expected; + + a.high = high; + a.low = low; + + libj2_ju_lsh_to_j2u(1U, shift, &expected); + libj2_j2u_nor_j2u_to_j2u(&a, &expected, &expected); + + r = (struct libj2_j2u){111, 222}; + libj2_j2u_nor_bit_to_j2u(&a, shift, &r); + EXPECT(a.high == high); + EXPECT(a.low == low); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_nor_bit_to_j2u(&r, shift, &r); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_nor_bit(&r, shift); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); +} + + +int +main(void) +{ + unsigned i; + + srand((unsigned)time(NULL)); + + for (i = 0; i < LIBJ2_J2U_BIT + 4U; i++) { + check(0, 0, i); + check(0, random_ju(), i); + check(0, UINTMAX_MAX, i); + check(random_ju(), 0, i); + check(random_ju(), random_ju(), i); + check(random_ju(), UINTMAX_MAX, i); + check(UINTMAX_MAX, 0, i); + check(UINTMAX_MAX, random_ju(), i); + check(UINTMAX_MAX, UINTMAX_MAX, i); + } + + return 0; +} + +#endif diff --git a/libj2_j2u_or_bit.c b/libj2_j2u_or_bit.c new file mode 100644 index 0000000..109d5b9 --- /dev/null +++ b/libj2_j2u_or_bit.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_or_bit(struct libj2_j2u *a, unsigned b); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_j2u_or_bit_to_j2u.c */ + +#endif diff --git a/libj2_j2u_or_bit_to_j2u.c b/libj2_j2u_or_bit_to_j2u.c new file mode 100644 index 0000000..fc2a235 --- /dev/null +++ b/libj2_j2u_or_bit_to_j2u.c @@ -0,0 +1,72 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_or_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +static void +check(uintmax_t high, uintmax_t low, unsigned shift) +{ + struct libj2_j2u a, r, expected; + + a.high = high; + a.low = low; + + libj2_ju_lsh_to_j2u(1U, shift, &expected); + libj2_j2u_or_j2u_to_j2u(&a, &expected, &expected); + + r = (struct libj2_j2u){111, 222}; + libj2_j2u_or_bit_to_j2u(&a, shift, &r); + EXPECT(a.high == high); + EXPECT(a.low == low); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_or_bit_to_j2u(&r, shift, &r); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_or_bit(&r, shift); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); +} + + +int +main(void) +{ + unsigned i; + + srand((unsigned)time(NULL)); + + for (i = 0; i < LIBJ2_J2U_BIT + 4U; i++) { + check(0, 0, i); + check(0, random_ju(), i); + check(0, UINTMAX_MAX, i); + check(random_ju(), 0, i); + check(random_ju(), random_ju(), i); + check(random_ju(), UINTMAX_MAX, i); + check(UINTMAX_MAX, 0, i); + check(UINTMAX_MAX, random_ju(), i); + check(UINTMAX_MAX, UINTMAX_MAX, i); + } + + return 0; +} + +#endif diff --git a/libj2_j2u_test_high_ju.c b/libj2_j2u_test_high_ju.c index 0d03b40..5b73c5e 100644 --- a/libj2_j2u_test_high_ju.c +++ b/libj2_j2u_test_high_ju.c @@ -17,8 +17,8 @@ main(void) for (h = 0; h < 10; h++) { a.low = h; for (i = 0; i < 128; i++) { + a.high = i; for (j = 0; j < 128; j++) { - a.high = i; if (i & j) EXPECT(libj2_j2u_test_high_ju(&a, j) == 1); else diff --git a/libj2_j2u_test_j2u.c b/libj2_j2u_test_j2u.c index 682da56..1c6725b 100644 --- a/libj2_j2u_test_j2u.c +++ b/libj2_j2u_test_j2u.c @@ -24,6 +24,7 @@ set_pattern(struct libj2_j2u *a, unsigned off, unsigned mod) } } + CONST static int expected(unsigned a_off, unsigned a_mod, unsigned b_off, unsigned b_mod) { @@ -45,6 +46,7 @@ expected(unsigned a_off, unsigned a_mod, unsigned b_off, unsigned b_mod) return 0; } + int main(void) { diff --git a/libj2_j2u_test_ju.c b/libj2_j2u_test_ju.c index 5752bf2..adb8dd4 100644 --- a/libj2_j2u_test_ju.c +++ b/libj2_j2u_test_ju.c @@ -17,8 +17,8 @@ main(void) for (h = 0; h < 10; h++) { a.high = h; for (i = 0; i < 128; i++) { + a.low = i; for (j = 0; j < 128; j++) { - a.low = i; if (i & j) EXPECT(libj2_j2u_test_ju(&a, j) == 1); else diff --git a/libj2_j2u_xnor_bit.c b/libj2_j2u_xnor_bit.c new file mode 100644 index 0000000..927a371 --- /dev/null +++ b/libj2_j2u_xnor_bit.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_xnor_bit(struct libj2_j2u *a, unsigned b); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_j2u_xnor_bit_to_j2u.c */ + +#endif diff --git a/libj2_j2u_xnor_bit_to_j2u.c b/libj2_j2u_xnor_bit_to_j2u.c new file mode 100644 index 0000000..cf91139 --- /dev/null +++ b/libj2_j2u_xnor_bit_to_j2u.c @@ -0,0 +1,72 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_xnor_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +static void +check(uintmax_t high, uintmax_t low, unsigned shift) +{ + struct libj2_j2u a, r, expected; + + a.high = high; + a.low = low; + + libj2_ju_lsh_to_j2u(1U, shift, &expected); + libj2_j2u_xnor_j2u_to_j2u(&a, &expected, &expected); + + r = (struct libj2_j2u){111, 222}; + libj2_j2u_xnor_bit_to_j2u(&a, shift, &r); + EXPECT(a.high == high); + EXPECT(a.low == low); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_xnor_bit_to_j2u(&r, shift, &r); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_xnor_bit(&r, shift); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); +} + + +int +main(void) +{ + unsigned i; + + srand((unsigned)time(NULL)); + + for (i = 0; i < LIBJ2_J2U_BIT + 4U; i++) { + check(0, 0, i); + check(0, random_ju(), i); + check(0, UINTMAX_MAX, i); + check(random_ju(), 0, i); + check(random_ju(), random_ju(), i); + check(random_ju(), UINTMAX_MAX, i); + check(UINTMAX_MAX, 0, i); + check(UINTMAX_MAX, random_ju(), i); + check(UINTMAX_MAX, UINTMAX_MAX, i); + } + + return 0; +} + +#endif diff --git a/libj2_j2u_xor_bit.c b/libj2_j2u_xor_bit.c new file mode 100644 index 0000000..d125e16 --- /dev/null +++ b/libj2_j2u_xor_bit.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_xor_bit(struct libj2_j2u *a, unsigned b); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_j2u_xor_bit_to_j2u.c */ + +#endif diff --git a/libj2_j2u_xor_bit_to_j2u.c b/libj2_j2u_xor_bit_to_j2u.c new file mode 100644 index 0000000..262648b --- /dev/null +++ b/libj2_j2u_xor_bit_to_j2u.c @@ -0,0 +1,72 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_j2u_xor_bit_to_j2u(const struct libj2_j2u *a, unsigned b, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(void) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + while (n--) + if (rand() < rand()) + r |= (uintmax_t)1 << n; + return r; +} + + +static void +check(uintmax_t high, uintmax_t low, unsigned shift) +{ + struct libj2_j2u a, r, expected; + + a.high = high; + a.low = low; + + libj2_ju_lsh_to_j2u(1U, shift, &expected); + libj2_j2u_xor_j2u_to_j2u(&a, &expected, &expected); + + r = (struct libj2_j2u){111, 222}; + libj2_j2u_xor_bit_to_j2u(&a, shift, &r); + EXPECT(a.high == high); + EXPECT(a.low == low); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_xor_bit_to_j2u(&r, shift, &r); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); + + r = a; + libj2_j2u_xor_bit(&r, shift); + EXPECT(libj2_j2u_eq_j2u(&r, &expected)); +} + + +int +main(void) +{ + unsigned i; + + srand((unsigned)time(NULL)); + + for (i = 0; i < LIBJ2_J2U_BIT + 4U; i++) { + check(0, 0, i); + check(0, random_ju(), i); + check(0, UINTMAX_MAX, i); + check(random_ju(), 0, i); + check(random_ju(), random_ju(), i); + check(random_ju(), UINTMAX_MAX, i); + check(UINTMAX_MAX, 0, i); + check(UINTMAX_MAX, random_ju(), i); + check(UINTMAX_MAX, UINTMAX_MAX, i); + } + + return 0; +} + +#endif diff --git a/libj2_kfs_j2u.c b/libj2_kfs_j2u.c new file mode 100644 index 0000000..af07619 --- /dev/null +++ b/libj2_kfs_j2u.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_kfs_j2u(struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_cfs_j2u.c */ + +#endif diff --git a/libj2_kfs_j2u_to_j2u.c b/libj2_kfs_j2u_to_j2u.c new file mode 100644 index 0000000..afc09fe --- /dev/null +++ b/libj2_kfs_j2u_to_j2u.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_kfs_j2u_to_j2u(const struct libj2_j2u *a, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_kfs_j2u.c */ + +#endif diff --git a/libj2_kls_j2u.c b/libj2_kls_j2u.c new file mode 100644 index 0000000..1c52f36 --- /dev/null +++ b/libj2_kls_j2u.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_kls_j2u(struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_cls_j2u.c */ + +#endif diff --git a/libj2_kls_j2u_to_j2u.c b/libj2_kls_j2u_to_j2u.c new file mode 100644 index 0000000..4b13153 --- /dev/null +++ b/libj2_kls_j2u_to_j2u.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_kls_j2u_to_j2u(const struct libj2_j2u *a, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_kls_j2u.c */ + +#endif diff --git a/libj2_parity_j2u.c b/libj2_parity_j2u.c new file mode 100644 index 0000000..5adafc6 --- /dev/null +++ b/libj2_parity_j2u.c @@ -0,0 +1,95 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline unsigned libj2_parity_j2u(const struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +static uintmax_t +random_ju(unsigned *popcount) +{ + size_t n = LIBJ2_JU_BIT; + uintmax_t r = 0; + *popcount = 0; + while (n--) { + if (rand() < rand()) { + r |= (uintmax_t)1 << n; + *popcount += 1U; + } + } + return r; +} + + +int +main(void) +{ + struct libj2_j2u a; + uintmax_t high, low; + unsigned i, high_n, low_n; + + srand((unsigned)time(NULL)); + + a.high = 0; + a.low = 0; + EXPECT(libj2_parity_j2u(&a) == 0); + EXPECT(a.high == 0); + EXPECT(a.low == 0); + + a.high = 0; + a.low = UINTMAX_MAX; + EXPECT(libj2_parity_j2u(&a) == (LIBJ2_JU_BIT & 1U)); + EXPECT(a.high == 0); + EXPECT(a.low == UINTMAX_MAX); + + a.high = UINTMAX_MAX; + a.low = 0; + EXPECT(libj2_parity_j2u(&a) == (LIBJ2_JU_BIT & 1U)); + EXPECT(a.high == UINTMAX_MAX); + EXPECT(a.low == 0); + + a.high = UINTMAX_MAX; + a.low = UINTMAX_MAX; + EXPECT(libj2_parity_j2u(&a) == (LIBJ2_J2U_BIT & 1U)); + EXPECT(a.high == UINTMAX_MAX); + EXPECT(a.low == UINTMAX_MAX); + + for (i = 0; i < 256; i++) { + a.high = high = random_ju(&high_n); + a.low = low = random_ju(&low_n); + EXPECT(libj2_parity_j2u(&a) == ((high_n + low_n) & 1U)); + EXPECT(a.high == high); + EXPECT(a.low == low); + + a.high = high = random_ju(&high_n); + a.low = low = 0; + EXPECT(libj2_parity_j2u(&a) == (high_n & 1U)); + EXPECT(a.high == high); + EXPECT(a.low == 0); + + a.high = high = random_ju(&high_n); + a.low = low = UINTMAX_MAX; + EXPECT(libj2_parity_j2u(&a) == ((high_n + LIBJ2_JU_BIT) & 1U)); + EXPECT(a.high == high); + EXPECT(a.low == UINTMAX_MAX); + + a.high = high = 0; + a.low = low = random_ju(&low_n); + EXPECT(libj2_parity_j2u(&a) == (low_n & 1U)); + EXPECT(a.high == 0); + EXPECT(a.low == low); + + a.high = high = UINTMAX_MAX; + a.low = low = random_ju(&low_n); + EXPECT(libj2_parity_j2u(&a) == ((LIBJ2_JU_BIT + low_n) & 1U)); + EXPECT(a.high == UINTMAX_MAX); + EXPECT(a.low == low); + } + + return 0; +} + +#endif diff --git a/libj2_sfc_j2u.c b/libj2_sfc_j2u.c new file mode 100644 index 0000000..1b91a7e --- /dev/null +++ b/libj2_sfc_j2u.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_sfc_j2u(struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_cfs_j2u.c */ + +#endif diff --git a/libj2_sfc_j2u_to_j2u.c b/libj2_sfc_j2u_to_j2u.c new file mode 100644 index 0000000..a1a9e17 --- /dev/null +++ b/libj2_sfc_j2u_to_j2u.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_sfc_j2u_to_j2u(const struct libj2_j2u *a, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_cfs_j2u.c */ + +#endif diff --git a/libj2_slc_j2u.c b/libj2_slc_j2u.c new file mode 100644 index 0000000..500f633 --- /dev/null +++ b/libj2_slc_j2u.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_slc_j2u(struct libj2_j2u *a); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_cls_j2u.c */ + +#endif diff --git a/libj2_slc_j2u_to_j2u.c b/libj2_slc_j2u_to_j2u.c new file mode 100644 index 0000000..874be05 --- /dev/null +++ b/libj2_slc_j2u_to_j2u.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +extern inline void libj2_slc_j2u_to_j2u(const struct libj2_j2u *a, struct libj2_j2u *res); +/* TODO Add man page */ + + +#else + +CONST int main(void) { return 0; } /* Tested in libj2_cls_j2u.c */ + +#endif |
