Jakemmarsh
Jakemmarsh

Reputation: 4661

bit shift multiplication loop

I have the following method written:

public static int hash2(String key, int tableSize) {
    int hashVal = 0;

    for(int i=0; i<key.length();i++) {
        hashVal = 37 * hashVal + key.charAt(i);
    }

    System.out.println(hashVal);

    hashVal %= tableSize;   
    if(hashVal < 0){
        hashVal += tableSize;
    }

    return hashVal;
}

I have been tasked with rewriting the for loop without using any multiplication or division. My only tools are addition and shifting of 16-bit binary numbers.

I realize that I need to somehow multiply hashVal by 37, and then add key.charAt(i) to this value. I have tried that multiple ways:

    for(int i=0; i<key.length();i++) {
        hashVal2 = hashVal2<<19 - hashVal2;
        hashVal2 += key.charAt(i);
    }

or

    for(int i=0; i<key.length();i++) {
        hashVal2 = hashVal2<<18 + hashVal2;
        hashVal2 += key.charAt(i);
    }

or

    for(int i=0; i<key.length();i++) {
        for(int j=0; j<37;j++) {
            hashVal2 += hashVal2;
        }
        hashVal2 += key.charAt(i);
    }

But none of these end up returning the same values for hashVal (or hashVal2) as the original method. Am I misunderstanding bit shifting, or is something with the loop the culprit? Not sure what else to try.

Upvotes: 0

Views: 1776

Answers (2)

Prabhakar
Prabhakar

Reputation: 133

Left shift by 1 bit would multiply the number by 2. So to multiply by 37 convert 37 into binary. It would be 100101

Number * 2^5 + Number * 2^2 + Number * 2^0
Number << 5 + Number << 2 + Number 

For loop would look like this:

for(int i=0; i<key.length();i++) {
    hashVal = (hashVal << 5) + (hashVal << 2) + hashVal + key.charAt(i);
}

Upvotes: 1

Ted Hopp
Ted Hopp

Reputation: 234807

Multiplying by 37 is the same as adding certain powers of 2:

x * 37 == x * (32 + 4 + 1)

This tells you how to shift, since:

32 == 25
4 == 22
1 == 20

Finally, x * 2i == (x << i) for all i. So to multiply x by 37, you can compute

(x << 5) + (x << 2) + (x)

The rest of the exercise should be fairly straightforward.

Upvotes: 4

Related Questions