/* * Oct 2003, Ben Winslow * * Thanks to Zinx for smacking me around with the obvious, and for his * highest_bit function. */ #define _ISOC99_SOURCE #include #include #define BIGTYPE long long #define MAX_BITS (sizeof(BIGTYPE) * 8) typedef unsigned BIGTYPE bignum_t; typedef signed BIGTYPE sbignum_t; static void print_bits(bignum_t, int, int); static int highest_bit(bignum_t, int); static void print_values(bignum_t, int); int main(int argc, char *argv[]) { bignum_t value; int offset = 0, width = 1, wholewidth = MAX_BITS; if (argc < 2 || argc > 4) { printf("usage: %s [offset [width]]\n", argv[0]); return 1; } value = strtoull(argv[1], NULL, 0); if (argc >= 3) { offset = (int)strtoul(argv[2], NULL, 0); if (argc == 4) width = (int)strtoul(argv[3], NULL, 0); } if (argc == 2) /* value only, round down the length to nearest nibble */ wholewidth = highest_bit(value, 4); else /* otherwise, round to smallest 32 bits */ wholewidth = highest_bit(value, 32); printf("Whole number:\n"); print_values(value, wholewidth); if (argc > 2) { bignum_t section; #define _s(n) ((n) == 1 ? "" : "s") printf("\nSelected section: %d bit%s starting %d bit%s from LSB\n", width, _s(width), offset, _s(offset)); #undef _s if (width == MAX_BITS) section = (value >> offset); else section = (value >> offset) & (((bignum_t)1 << width) - 1); print_values(section, width); } return 0; } static void print_values(bignum_t value, int bitwidth) { printf(" Dec: %lld\n", (sbignum_t)value); printf(" Dec: %llu (unsigned)\n", value); printf(" Hex: %llx\n", value); printf(" Oct: %llo\n", value); printf(" Bin: "); print_bits(value, 0, bitwidth); printf("\n"); } static void print_bits(bignum_t value, int offset, int width) { int x; for (x = width - 1; x >= offset; x--) printf("%d", ((value >> offset) & ((bignum_t)1 << x)) > 0 ? 1 : 0); } /* <3 zinx */ static int highest_bit(bignum_t bignum, int granularity) { int ret = 0; if (MAX_BITS > 64) { printf("warning: highest_bit does not support over 64 bits!\n"); printf(" bitwise representations will never be truncated.\n"); return MAX_BITS; } #ifndef LINT if ((bignum & 0xffffffff00000000LL) > 0) { ret += 32; bignum >>= 32; } #endif if ((bignum & 0xffff0000) > 0) { ret += 16; bignum >>= 16; } if ((bignum & 0xff00) > 0) { ret += 8; bignum >>= 8; } if ((bignum & 0xf0) > 0) { ret += 4; bignum >>= 4; } if ((bignum & 0xc) > 0) { ret += 2; bignum >>= 2; } if ((bignum & 0x2) > 0) { ret += 1; bignum >>= 1; } if ((bignum & 0x1) > 0) { ret += 1; } /* round it up */ ret += granularity - 1; ret -= ret % granularity; return ret; }