diff options
Diffstat (limited to 'src/stdlib')
| -rw-r--r-- | src/stdlib/bytes.c | 8 | ||||
| -rw-r--r-- | src/stdlib/bytes.h | 1 | ||||
| -rw-r--r-- | src/stdlib/integers.c | 20 | ||||
| -rw-r--r-- | src/stdlib/integers.h | 2 |
4 files changed, 31 insertions, 0 deletions
diff --git a/src/stdlib/bytes.c b/src/stdlib/bytes.c index b5c10aa2..48c8b93b 100644 --- a/src/stdlib/bytes.c +++ b/src/stdlib/bytes.c @@ -49,6 +49,14 @@ public Text_t Byte$hex(Byte_t byte, bool uppercase, bool prefix) { return text; } +public bool Byte$get_bit(Byte_t 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, I(8)) > 0) + fail("Bit index is too large! There are only 8 bits in a byte, but index is: ", bit_index); + return ((x & (Byte_t)(1L << (Int64$from_int(bit_index, true)-1L))) != 0); +} + #ifdef __TINYC__ #define __builtin_add_overflow(x, y, result) ({ *(result) = (x) + (y); false; }) #endif diff --git a/src/stdlib/bytes.h b/src/stdlib/bytes.h index 5c64687d..e733c274 100644 --- a/src/stdlib/bytes.h +++ b/src/stdlib/bytes.h @@ -30,5 +30,6 @@ extern const Byte_t Byte$max; extern const TypeInfo_t Byte$info; Text_t Byte$hex(Byte_t byte, bool uppercase, bool prefix); +bool Byte$get_bit(Byte_t x, Int_t bit_index); // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 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; \ diff --git a/src/stdlib/integers.h b/src/stdlib/integers.h index 4eaac916..beb26bd6 100644 --- a/src/stdlib/integers.h +++ b/src/stdlib/integers.h @@ -29,6 +29,7 @@ Text_t type_name ## $hex(c_type i, Int_t digits, bool uppercase, bool prefix); \ Text_t type_name ## $octal(c_type i, Int_t digits, bool prefix); \ List_t type_name ## $bits(c_type x); \ + bool type_name ## $get_bit(c_type x, Int_t bit_index); \ Closure_t type_name ## $to(c_type first, c_type last, Optional ## type_name ## _t step); \ Closure_t type_name ## $onward(c_type first, c_type step); \ PUREFUNC Optional ## type_name ## _t type_name ## $parse(Text_t text); \ @@ -105,6 +106,7 @@ Int_t Int$abs(Int_t x); Int_t Int$power(Int_t base, Int_t exponent); Int_t Int$gcd(Int_t x, Int_t y); OptionalInt_t Int$sqrt(Int_t i); +bool Int$get_bit(Int_t x, Int_t bit_index); #define BIGGEST_SMALL_INT 0x3fffffff #define SMALLEST_SMALL_INT -0x40000000 |
