From 1fc2082b4ccc2b75fba892bc9e27e9a5a3d821bf Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 15 Feb 2017 18:55:29 -0500 Subject: ability to declare const bitfields See #261 --- src/bignum.cpp | 45 +++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 26 deletions(-) (limited to 'src/bignum.cpp') diff --git a/src/bignum.cpp b/src/bignum.cpp index e3b661e81a..9723b50994 100644 --- a/src/bignum.cpp +++ b/src/bignum.cpp @@ -46,42 +46,35 @@ void bignum_init_bignum(BigNum *dest, BigNum *src) { safe_memcpy(dest, src, 1); } +static int u64_log2(uint64_t x) { + int result = 0; + for (; x != 0; x >>= 1) { + result += 1; + } + return result; +} + bool bignum_fits_in_bits(BigNum *bn, int bit_count, bool is_signed) { assert(bn->kind == BigNumKindInt); if (is_signed) { - if (bn->is_negative) { - if (bn->data.x_uint <= ((uint64_t)INT8_MAX) + 1) { - return bit_count >= 8; - } else if (bn->data.x_uint <= ((uint64_t)INT16_MAX) + 1) { - return bit_count >= 16; - } else if (bn->data.x_uint <= ((uint64_t)INT32_MAX) + 1) { - return bit_count >= 32; - } else { - return bit_count >= 64; - } - } else if (bn->data.x_uint <= (uint64_t)INT8_MAX) { - return bit_count >= 8; - } else if (bn->data.x_uint <= (uint64_t)INT16_MAX) { - return bit_count >= 16; - } else if (bn->data.x_uint <= (uint64_t)INT32_MAX) { - return bit_count >= 32; + uint64_t max_neg; + uint64_t max_pos; + if (bit_count < 64) { + max_neg = (1ULL << (bit_count - 1)); + max_pos = max_neg - 1; } else { - return bit_count >= 64; + max_pos = ((uint64_t)INT64_MAX); + max_neg = max_pos + 1; } + uint64_t max_val = bn->is_negative ? max_neg : max_pos; + return bn->data.x_uint <= max_val; } else { if (bn->is_negative) { return bn->data.x_uint == 0; } else { - if (bn->data.x_uint <= UINT8_MAX) { - return bit_count >= 8; - } else if (bn->data.x_uint <= UINT16_MAX) { - return bit_count >= 16; - } else if (bn->data.x_uint <= UINT32_MAX) { - return bit_count >= 32; - } else { - return bit_count >= 64; - } + int required_bit_count = u64_log2(bn->data.x_uint); + return bit_count >= required_bit_count; } } } -- cgit v1.2.3