aboutsummaryrefslogtreecommitdiff
path: root/src/stdlib/integers.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-06-26 13:06:47 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-06-26 13:06:47 -0400
commit8a4d5dc57b14e7c947c25970bb4d4f4ef91450f4 (patch)
treee36042760c7c22d5a08777939484c06830d73404 /src/stdlib/integers.c
parentc2653404944dbd5a6f737877f0bad6fd1de018f1 (diff)
Add get_bit() method for Ints and Bytes
Diffstat (limited to 'src/stdlib/integers.c')
-rw-r--r--src/stdlib/integers.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/stdlib/integers.c b/src/stdlib/integers.c
index 7c623663..018798ec 100644
--- a/src/stdlib/integers.c
+++ b/src/stdlib/integers.c
@@ -359,6 +359,19 @@ public OptionalInt_t Int$sqrt(Int_t i)
return Int$from_mpz(result);
}
+public bool Int$get_bit(Int_t x, Int_t bit_index)
+{
+ mpz_t i;
+ mpz_init_set_int(i, x);
+ if (Int$compare_value(bit_index, I(1)) < 0)
+ fail("Invalid bit index (expected 1 or higher): ", bit_index);
+ if (Int$compare_value(bit_index, Int$from_int64(INT64_MAX)) > 0)
+ fail("Bit index is too large! ", bit_index);
+
+ int is_bit_set = mpz_tstbit(i, (mp_bitcnt_t)(Int64$from_int(bit_index, true)-1));
+ return (bool)is_bit_set;
+}
+
typedef struct {
OptionalInt_t current, last;
Int_t step;
@@ -620,6 +633,13 @@ public void Int32$deserialize(FILE *in, void *outval, List_t *pointers, const Ty
} \
return bit_list; \
} \
+ public bool KindOfInt ## $get_bit(c_type x, Int_t bit_index) { \
+ if (Int$compare_value(bit_index, I(1)) < 0) \
+ fail("Invalid bit index (expected 1 or higher): ", bit_index); \
+ if (Int$compare_value(bit_index, Int$from_int64(sizeof(c_type)*8)) > 0) \
+ fail("Bit index is too large! There are only ", sizeof(c_type)*8, " bits, but index is: ", bit_index); \
+ return ((x & (c_type)(1L << (Int64$from_int(bit_index, true)-1L))) != 0); \
+ } \
typedef struct { \
Optional##KindOfInt##_t current, last; \
KindOfInt##_t step; \