-3

I want to make a bitwise AND computation over integers, but without converting them to binary numbers.
For example, I have a integer "10111" (it is integer, not binary) and another integer "01001". I want bitwise AND of these numbers without converting them to binary and then making bitwise AND. I know it is not bitwise what I ask, but I want something similar to this. I know it can be interpreted initially as binary, converted to decimal and then do bitwise AND, but I do not want that. I want something like this:

int a;
int b;
int temp;
double result;

temp = a & b;

while (result != 0) {
        if (result % 10 == 1)
            count++;
        result /= 10;
    }

int length = floor(log10(abs(a))) + 1;
result = count / length;
return result;

I want this to check similarity of the Bag of Words(from natural language processing, string of 0s and 1s). I am importing Bag of Words in Monetdb, Column type should be Integer (Not string). If I have for example "10111" and "01001" in the Integer type cells, I want to get "00001" and fraction 1/5, because only 1 positions matches.


Thanks in advance

Masyaf
  • 843
  • 1
  • 9
  • 17
  • 3
    Integers are binary numbers. The numbers are represented in the memory in binary form. There is nothing to convert. – gluk47 Mar 25 '16 at 13:00
  • 2
    What is the problem in using bitwise and operator `&`? – Mohit Jain Mar 25 '16 at 13:00
  • 3
    Just to be clear: you want to AND the decimal numbers `10111` and `01001` and get a decimal result **as if** they represent binary? (Be careful, by the way, because the notation `01001` may be misunderstood as *octal*. (That's what is supposed to happen.)) – Jongware Mar 25 '16 at 13:00
  • Numbers in computers _are binary by nature_, so you can't work with numbers without converting them to binary. – ForceBru Mar 25 '16 at 13:01
  • My bad, I explained it badly. For example I have integer 10111 and 01001. If I make & of them I want to get another integer 00001. If I make & of them, C will convert them to their binary representation, "10 0111 0111 1111" and "11 1110 1001" and then will make Bitwise AND. – Masyaf Mar 25 '16 at 13:05
  • @Masyaf, no, `10111 AND 01001` is equal to `873` – ForceBru Mar 25 '16 at 13:06
  • @Masyaf no. Do you mean character strings, like "0101101", rather than integers? – Martin James Mar 25 '16 at 13:08
  • Integer types in C ARE binary representations. No conversion is required. We are all struggling to understand what you mean... :( – Martin James Mar 25 '16 at 13:09
  • @ ForceBru, seems I am really bad in explaining so, I have a bag of words (string of 0s and 1s, representing availability of words in the sentence). I want to compare two bag of words (string of 0s and 1s). I have to compare corresponding positions of each bag of words (it is similar to BItwise AND), get all matching 1s and get their fraction. If I have 10 "1"s matching from 100 length bag of words, fraction will be 0.1. Did I explain it better? – Masyaf Mar 25 '16 at 13:10
  • I think OP has 2 integers which are equal to 10111 and 01001 (base 10) but even though they are in base 10, he wants to make an 'AND' operation as if they were base 2. Don't know why it's like that but ... That's how I understand the thing. – Unda Mar 25 '16 at 13:11
  • @Unda exactly thanks! I am importing bag of words in Monetdb. It does not have any binary types, only integers. I want a C function which will compare two cells of type BigInt and give me what I want. Tried with character array, does not work. – Masyaf Mar 25 '16 at 13:13
  • @Masyaf If you have strings to begin with (instead of ints) you may have a cleaner solution if you convert them to ints without forgetting to tell the converter the strings are binary integers (as shown in [this solution](http://stackoverflow.com/a/7021750/2508277)). Then you cound use a proper bitwise AND operator `&` – Unda Mar 25 '16 at 13:17
  • 1
    Please edit your question to include sample input and output. Then someone might be able to figure out what you mean. – M.M Mar 25 '16 at 13:19

3 Answers3

1

Might be a bit bulky, but it kind of works) You can optimize it yourself. I hope that I get you correctly.

IDEOne demo

#include <stdio.h>

unsigned int weirdAnd(unsigned int a, unsigned int b) {
    unsigned int result = 0;
    unsigned int coef = 1;
    while (a && b) {
        result += ((a % 10) && (b % 10)) * coef;
        coef *= 10;
        a /= 10;
        b /= 10;
    }
    return result;
}

unsigned int weirdOr(unsigned int a, unsigned int b) {
    unsigned int result = 0;
    unsigned int coef = 1;
    while (a || b) {
        result += ((a % 10) || (b % 10)) * coef;
        coef *= 10;
        a /= 10;
        b /= 10;
    }
    return result;
}

int main(void) {
    // your code goes here
    unsigned int a = 10110;
    unsigned int b = 10011;
    printf("%u and \n%u = \n%u\n\n", a, b, weirdAnd(a, b));
    printf("%u or  \n%u = \n%u\n\n", a, b, weirdOr(a, b));
    return 0;
}

Output:

10110 and 10011 = 10010

10110 or 10011 = 10111

FreeNickname
  • 7,398
  • 2
  • 30
  • 60
  • I think that's effectively what he wanted – Unda Mar 25 '16 at 13:29
  • A better `while` test for the `weirdAND` loop is `a && b`. If either is zero, you're done, right? – Tom Karzes Mar 25 '16 at 13:33
  • @FreeNickname thanks for the answer. The only problem with this code is that "0" & "0" is 0 not 1. But other than that I will try to adapt it to Monetdb. – Masyaf Mar 25 '16 at 13:38
  • @TomKarzes, that's right. Thank you for a suggestion) – FreeNickname Mar 25 '16 at 13:57
  • @Masyaf you're welcome :) I don't understand the second part of your comment though. I've just run the code for `a = 0`, `b = 0`, and the answer is `0` for both `and` and `or`. – FreeNickname Mar 25 '16 at 13:58
  • @Masyaf: It would be true for `xor` – but that was not the question. – Jongware Mar 25 '16 at 14:03
  • Sorry my bad, too exhausted from all of this stuff. Just a question, what does `coef` do? – Masyaf Mar 25 '16 at 14:29
  • @Masyaf, that's just my way of writing "coefficient" :) We process digits one by one, starting from the least significant. So first we get result from the first digit from the right, then for the second, etc. The result is a single digit (1 or 0). We have to shift it to put it to the appropriate position. If we worked with bits directly, we'd use bit shifts (`<<` / `>>`). In base 10 we multiply by 1, 10, 100, etc. And we store this multiplier in the `coef` variable. So `10111 = 1 * 1 + 1 * 10 + 1 * 100 + 0 * 1.000 + 1 * 10.000`. – FreeNickname Mar 25 '16 at 15:04
  • @FreeNickname thanks a lot. I Still should adapt it to Monetdb, but the function is good. – Masyaf Mar 25 '16 at 15:11
0

The problem is that and works on bits only, and it does not care if the input numbers are given in decimals, octal, hexadecimal, or any other way. To force and to work correctly, you must give it an input in 'binary', that is, only ones and zeroes. To do so you need to grab each digit of the input numbers as if they are binary digits.

The following works as expected:

#include <stdio.h>

int cheap_pow (int base, int exponent)
{
    int result = base;
    while (exponent-- > 0)
        result *= base;
    return result;
}

int main (void)
{
    int a = 10111, b = 1001 ;
    int result, factor;

    printf ("BAD:  %05d AND %05d = %05d\n", a, b, a & b);

    printf ("GOOD: %05d AND %05d = ");

    result = 0;
    factor = 1;
    while (a | b)
    {
        result += factor * ((a & 1) and (b & 1));
        factor *= 10;
        a /= 10;
        b /= 10;
    }
    printf ("%05d\n", result);
}

but you must be careful when defining your inputs. When written directly into your source code, a value b = 01001 will be interpreted by the C compiler as octal (base 8), rather than decimal; and it will have the (decimal) value 513. It's just a Rule of C.

If your input comes from elsewhere, you don't need to take this into account – except when you use a standard function such as strtol, where you should carefully read the documentation because it does the same thing:

If base is zero or 16, the string may then include a "0x" prefix, and the number will be read in base 16; otherwise, a zero base is taken as 10 (decimal) unless the next character is '0', in which case it is taken as 8 (octal).

An additional note is this program only will work in the range for signed int, that is (currently) up to 10 "binary" digits. If you need some more, you could switch to a larger type; but beyond that, you are better off with a not-numerical solution and use a character strings throughout.

Jongware
  • 22,200
  • 8
  • 54
  • 100
-2
int a, b;
int tmp = a & b;
int res = 0;

while ((tmp != 0 &&) (tmp / 10 != 0)){
    int dig = tmp % 10;
    res = (dig == 1)? ++res: res;
    tmp /= 10;       
}

Try this.

Silvio
  • 1
  • 3