C中的Bitand函数

时间:2016-03-25 12:57:28

标签: c

我想对整数进行按位AND计算,但不将它们转换为二进制数。
例如,我有一个整数" 10111" (它是整数,而不是二进制)和另一个整数" 01001"。我想要这些数字的按位AND,而不是将它们转换为二进制,然后进行按位AND。我知道这不符合我的要求,但我想要类似的东西。我知道它最初可以解释为二进制,转换为十进制然后按位AND,但我不希望这样。我想要这样的东西:

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;

我希望这能检查Bag of Words的相似性(来自自然语言处理,0和1的字符串)。我在Monetdb中导入Bag of Words,列类型应该是Integer(不是字符串)。如果我有例如" 10111"和" 01001"在整数类型的单元格中,我想得到" 00001"和1/5分数,因为只有1个位置匹配。


提前致谢

3 个答案:

答案 0 :(得分:1)

可能有点笨重,但它有点工作)你可以自己优化它。我希望我能帮到你。

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;
}

输出:

  

10110和10011 = 10010

     

10110或10011 = 10111

答案 1 :(得分:0)

问题是and仅适用于位,并不关心输入数字是以十进制,八进制,十六进制还是任何其他方式给出的。要强制and正常工作,必须以“二进制”方式输入,即只有1和0。为此,您需要获取输入数字的每个数字,就像它们是二进制数字一样。

以下按预期方式工作:

#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);
}

但是必须在定义输入时要小心。直接写入源代码时,C编译器将值b = 01001解释为 octal (基数为8),而不是十进制;它将具有(十进制)值513。这只是一个C规则。

如果您的输入来自其他地方,则无需考虑这一点 - 除非您使用标准功能,例如strtol,您应该谨慎read the documentation,因为它同样如此事情:

  

如果 base 为零或16,则字符串可能包含“0x”          前缀,数字将在16位读取;否则,为零          除非下一个字符为'0',否则 base 取10(十进制)          在哪种情况下,它被视为8(八进制)。

另外需要注意的是,此程序仅适用于signed int的范围,即(当前)最多10个“二进制”数字。如果你需要一些,你可以切换到更大的类型;但除此之外,你最好使用非数值解决方案,并在整个过程中使用字符串。

答案 2 :(得分:-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;       
}

试试这个。