0

I have a bignum formatted like a string like this: "123456789123456789123456789" and I need to check if a specified bit is set. The components are single digits in this string.

Usually I would do it like this if I wanted to check if bit 54 is set: NyNumber&(1<<54)

The problem is that I don't have AND or SHIFT in the bignum library I'm using.

So the question is; How can I check if a bit is set in a number formatted like a string with arbitrary size?

Edit: Just to clarify: I'm using a small scripting language called Autoit3 with the following library: http://www.autoitscript.com/forum/topic/83529-bignum-udf which represents BigNums as strings.

monoceres
  • 4,722
  • 4
  • 38
  • 63

2 Answers2

1

First of all, you can (and should) use a library for handling Arbitrary Precision numbers.

In java you have BigInteger, and in C++ you can use Gnu's Big Num

If you don't want to do this (and I assume you are not looking for performance), you can:

  • convert the string to it's 2-complement representation and check the index.

  • create a bitwise and operation and convert the string with the binary representation of what index you want (for example "0100") to base 10.

  • Bit shifting is the same as dividing by two, so, if you want to bitshift 54 bits, you should divide the number by 2^54. Then, you can just check if the number is even or odd, if it's even, then the bit isn't set.

If you are using the last method, you can do something like:

bool bitCheck (number, bitIndex) 
    pow = 2^bitIndex
    shifted = number / pow
    return (shifted % 2) == 0

ps: If you use gmp, you can check this page

finnw
  • 47,861
  • 24
  • 143
  • 221
Marco
  • 2,796
  • 19
  • 24
0

Convert your string into binary string and then check the 54th index. For java, you may try BigInteger class instead.

    BigInteger bi = new BigInteger("123456789123456789123456789");
    boolean hasBitSet = bi.equals(bi.setBit(54)); 

Edit:

    byte[] b = "123456789123456789123456789".getBytes("US-ASCII");
    int maxIndex = b.length - 1;
    for (int bitIdx = 0; bitIdx < (b.length * 8); bitIdx++) {

        int index =  maxIndex - (bitIdx / 8);
        int remainder = bitIdx % 8;

        boolean hasBitSet = (((b[index] & 0xff)) & (1 << remainder)) != 0;
        System.out.println( bitIdx + (hasBitSet ? " has set" : " has not set") );

    }
Prince John Wesley
  • 62,492
  • 12
  • 87
  • 94
  • I'm not using java, but a small language with no bignum support. I thought of converting it to a binary string, but this seems ineffective since the string could be several hundred digits long. Wouldn't it be possible to calculate which component that corrensponds to the specific bit and do a regular AND on it? – monoceres Oct 26 '11 at 13:20
  • @monoceres: find the byte index: length of the string - 54/8(quotient) - 1(if 54/8 has remainder). then compare the (8 - remainder of 54/8) bit from the character in the index. i assume that the characters are 1 byte sized type. – Prince John Wesley Oct 26 '11 at 13:26
  • That only works if you use ascii strings, if you use multibyte strings you would get very odd results. – Marco Oct 26 '11 at 13:31