带着几分阵列问题 [英] Problems with a bit array

查看:141
本文介绍了带着几分阵列问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个初始化位阵列宏。在typeBitVector_t名称[0]我保存它的大小,一切我使用埃拉托色尼的实际筛。这就是为什么我总是以1递增指数/ LIMIT这是code:

 的typedef unsigned long类型typeBitVector_t;
的#define LIMIT(8 * sizeof的(无符号长))
#定义createArray(名称,大小)\\
    typeBitVector_t名= {大小,0} [1 +尺寸/ LIMIT +((大小%为限)!= 0)];
#定义whatSize(名)\\
    名称[0]
#定义setBitValue(名称,索引值)\\
    (名称[(索引/ LIMIT)+1] =(值))? (名称[(索引/ LIMIT)+1] | =(1 <<;&LT;(指数%为限))):(名称[(索引/ LIMIT)+1]放大器; =〜(1 <<;&LT;(指数%为限)));
#定义returnBitValue(名称,指数)\\
    (名称[(索引/ LIMIT)+1]及(1 LT;≤(指数%为限)))? 1:0INT主要(无效)
{
    createArray(myArray的,100);
    无符号长的边界=(无符号长)的sqrt(100);    的for(int i = 2; I&LT; =界限;我++)
    {
        如果((returnBitValue(myarray的,I))== 0)
        {
            对于(INT J =我;我* J&LT; =界限; J ++)
            {
                setBitValue(myarray的,我*Ĵ,1);
                的printf(关于索引%的位的值为%d个\\ N,我*Ĵ,returnBitValue(myarray的,我* j)条);
            }
        }
    }    的printf(\\ NTEST出去索引%循环\\ n此位的值为%d个\\ N,8,returnBitValue(myarray的,8));
}

我附上该程序的输出:

  $ ./program
关于指数4位的值为1
关于指数6位的值为1
在指数8位的值为1
索引10位的值为1
在指数9位的值为1考出周期
在指数8位的值为0

所以筛在循环工作的精(它现在列出2和10之间的每一个非黄金价值),而是出于它的重置周期?问题出在哪里?


解决方案

  returnBitValue(myarray的,我* j)条

扩展到

 (名称[(我*焦耳/ LIMIT)+1]及(1 LT;≤(我*Ĵ%为限)))? 1:0

这是从不同的你可能是打算:

 (名称[((我* j)条/ LIMIT)+1]及(1 LT;≤((我* j)条%为限)))? 1:0

所以,最起码,你需要在宏展开周围添加首页圆括号。但它仍然将打破,如果你尝试做一些像

  returnBitValue(myarray的,我++)

所以最好不要在所有的,如果你能避免它(虽然我明白,这似乎是一个特定的条件,在这种情况下不使用的功能)使用宏。

您也有一些更多的问题 setBitValue

 (名称[((索引)/ LIMIT)+1] =(值))? (... | = ...):(...&放大器; = ...)

您大概意思

 名称[((指数)/ LIMIT)+1] =(值)? (... | ...)(...&安培; ...)

您也有一个潜在的整数溢出: 1 已键入 INT ,但你把它当作一个。使用 1L 代替。

I have macros which initialize a bit array. In typeBitVector_t name[0] I store its size, everything else I use for the actual sieve of eratosthenes. That's why I always increment index/LIMIT by 1. This is the code:

typedef unsigned long typeBitVector_t;
#define LIMIT (8*sizeof(unsigned long))
#define createArray(name,size) \
    typeBitVector_t name[1 + size/LIMIT + ((size%LIMIT) != 0)] = {size, 0};    
#define whatSize(name) \
    name[0]
#define setBitValue(name, index, value) \
    (name[(index/LIMIT)+1] = (value)) ? (name[(index/LIMIT)+1] |= (1<<(index%LIMIT))) : (name[(index/LIMIT)+1] &= ~(1<<(index%LIMIT)));
#define returnBitValue(name, index) \
    (name[(index/LIMIT)+1] & (1<<(index%LIMIT))) ? 1 : 0

int main(void)
{
    createArray(myArray,100);
    unsigned long bounds = (unsigned long) sqrt(100);

    for(int i = 2; i <= bounds; i++)
    {
        if((returnBitValue(myArray,i)) == 0)
        {
            for(int j = i; i * j <= bounds; j++)
            {
                setBitValue(myArray, i*j, 1);
                printf("The bit on index %d has the value %d\n", i*j, returnBitValue(myArray, i*j));
            }
        }
    }

    printf("\nTest out of the cycle\nThe bit on index %d has the value %d\n", 8, returnBitValue(myArray, 8));
}

I enclose the output of this program:

$ ./program
The bit on index 4 has the value 1
The bit on index 6 has the value 1
The bit on index 8 has the value 1
The bit on index 10 has the value 1
The bit on index 9 has the value 1

Test out of the cycle
The bit on index 8 has the value 0

So the sieve is working "fine" in the cycle (it now lists every non prime value between 2 and 10) but out of the cycle it's reset? Where is the problem?

解决方案

returnBitValue(myArray, i*j)

Expands to

(name[(i*j/LIMIT)+1] & (1<<(i*j%LIMIT))) ? 1 : 0

Which is different from what you probably intended:

(name[((i*j)/LIMIT)+1] & (1<<((i*j)%LIMIT))) ? 1 : 0

So at the very least you will need to add parantheses around index in the macro expansion. But it will still break if you try to do something like

returnBitValue(myArray, i++)

so better don't use macros at all if you can avoid it (although I understand that it seems to be a specific condition to not use functions in this case).

You also have some more problems in setBitValue:

(name[((index)/LIMIT)+1] = (value)) ? (... |= ...) : (... &= ...)

You probably meant

name[((index)/LIMIT)+1] = (value) ? (... | ...) : (... & ...)

You also have a potential integer overflow: 1 has type int, but you treat it as a long. Use 1L instead.

这篇关于带着几分阵列问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆