Почему этот код не выполняет свою работу? - PullRequest
0 голосов
/ 14 апреля 2010

Я хочу создать программу, которая записывает все простые числа в файл (я знаю, что есть популярный алгоритм "Сито Эратосфена", но я пытаюсь сделать это самостоятельно). Я пытаюсь устранить все сложности для байтов, которые все еще имеют значение 1, а затем записать их в файл.

#include <iostream>
#include <stdlib.h>  
#include <stdio.h>

void afficher_sur_un_ficher (FILE* ficher, int nb_bit);
char el_mask (int x);

int main()
{
    FILE* p_fich;
    char tab[4096], mask, eli_mask;
    int nb_bit = 0, x, f;

    for (int i = 0; i < 4096; i++)
    {
        tab[i] = 0xff;
    }

    for (int i = 0; i < 4096; i++)
    {
        for (mask = 0x01; mask != 0; mask <<= 1)
        {
            if ((tab[i] & mask) != 0)
            {
                x = nb_bit; 
                while ((x > 1) && (x < 16384))
                {
                    eli_mask = el_mask (x);
                    f = x / 8;
                    tab[f] = tab[f] ^ eli_mask;
                    x = x + nb_bit;
                }
                afficher_sur_un_ficher (p_fich, nb_bit);
            }
            nb_bit++;
        }
    }
    system ("PAUSE");
    return 0;
}

void afficher_sur_un_ficher (FILE* ficher, int nb_bit)
{
    ficher = fopen ("res.txt", "a+");
    fprintf (ficher, "%d \t", nb_bit);
    int static z;
    z = z + 1;
    if (z % 10 == 0)
        fprintf (ficher, "\n");
    fclose (ficher);
}

char el_mask (int x)
{
    x = x % 8;
    switch (x)
    {
        case 0:
            x = 0b00000001;
        break;
        case 1:
            x = 0b00000010;
        break;
        case 2:
            x = 0b00000100;
        break;
        case 3:
            x = 0b00001000;
        break;
        case 4:
            x = 0b00010000;
        break;
        case 5 :
            x = 0b00100000;
        break;
        case 6 :
            x = 0b01000000;
        break;
        case 7:
            x = 0b10000000;
        break;
    }
    return x;
}

Ответы [ 3 ]

5 голосов
/ 14 апреля 2010

Кажется, что есть проблема в цикле, который пытается очистить биты, указывающие не простые числа:

while (( x > 1 )&&(x < 16384))
{
    tab[i] = tab[i] ^ mask ;
    x = x * 2 ;
}

Поскольку i не изменяется в этом цикле, вы, по сути, включаете и выключаете один и тот же бит, увеличивая x. Помимо фиксирования индекса в tab[], вы, вероятно, захотите изменить операцию с xor (^) на что-то, что будет очищать бит безоговорочно - как только бит очищен, вам не нужно обрабатывать этот бит снова для другой фактор для «сброса» бита. Обратите внимание, что простое увеличение i не будет делать, так как кратные значения x в других элементах tab могут не совпадать с битовым смещением (в действительности, один элемент tab[] может содержать несколько кратных x).

Даже если вы исправите эту проблему, я думаю, что цикл, возможно, не будет выполнять то, что вы ожидаете, поскольку x = x * 2; не проходит x через его кратные числа - в итоге вы пропустите некоторые не простые числа.

Некоторое исследование о том, как работает «Сито Эратосфена», может помочь.

1 голос
/ 14 апреля 2010

Вы можете немного упростить свою основную функцию:

int main (int argc, char** argv) {
    FILE* p_fich;
    char tab[4096] , mask;
    int nb_bit = 0 , x;

    memset(tab, 0xFF, 4096);
    for (int i = 0; i < 4096; i++) {
        for (mask = 0x01; mask != 0; mask <<= 1) {
            if ((tab[i] & mask) != 0) {
                for (x = nb_bit; (x > 1) && (x < 0x4000), x<<=1)
                    tab[i] ^= mask;
                afficher_sur_un_ficher (p_fich, nb_bit);
            }
            nb_bit++;
        }
    }
    system ("PAUSE");
    return 0;
}

Теперь, чтобы ответить на ваш вопрос: Ваша функция afficher_sur_un_ficher будет печатать все, что вы ей передадите, и эта функция вызывается для каждой итерации цикла, где ((tab[i] & mask) != 0) равно true. Поскольку вы инициализируете каждый tab[i] байт 0xFF, маскирование любой заданной комбинации битов всегда приведет к тому, что оператор if оценит true. Вы изменяете значение tab[i], но как только вы это сделаете, вы больше не используете этот бит, поэтому это не меняет того факта, что оператор if всегда будет принят. Вот почему вы видите каждую запись в журнале.

Edit: Если вы упростите весь код, который не влияет на решение о выводе или значение для вывода, вы получите следующее:

memset(tab, 0xFF, 4096);
for (int i = 0; i < 4096; i++) {
    for (mask = 0x01; mask != 0; mask <<= 1) {
        afficher_sur_un_ficher (p_fich, nb_bit);
        nb_bit++;
    }
}

Как видите, этот код будет печатать возрастающую последовательность целых чисел (от 0 до (4096 * 8) -1) и полностью не зависит от массива tab и от конкретных значений i и mask. Я думаю, что в вашей реализации алгоритма чего-то не хватает. У вас есть ссылка на описание алгоритма, который вы пытаетесь реализовать? Или это алгоритм, который вы разработали? (Извините, я не понял вашего описания вашего алгоритма, который вы добавили в вопрос)

1 голос
/ 14 апреля 2010

Может быть, я что-то упускаю, но это кажется странным. Я не помню общих простых алгоритмов, но, например,

(excerpts) tab[i] = 0xff ; mask = 0x01 ;</p> <p>for (int j = 0 ; j < 8 ; j++) { if ((tab[i] & mask) != 0 ) mask = mask<<1 ;

Это означает, что вы всегда будете идти 8 раз - так зачем проверять '&'?

Еще один,

x = nb_bit ; while (( x > 1 )&&(x < 16384)) { tab[i] = tab[i] ^ mask ; x = x * 2 ; }

Это просто триггеры на каждой итерации. Это то, что вы хотите?

Наконец, поскольку я не знаю, что вы хотите сделать, будьте осторожны с битовой длиной ваших объектов. Вы можете бросить флоп

0000 0000 1111 1111 ^ 0000 0001

или

1111 1111 1111 1111 ^ 0000 00001

Поскольку я не совсем понимаю, что вы пытаетесь сделать, не уверен, что это может быть связано.

РЕДАКТИРОВАТЬ (после комментария Хамзы):

Да. Этот цикл выполняет следующее: сравни / 'и'

1111 1111 1111 1111

с

      0000 0001
      0000 0010
      0000 0100,

и это всегда будет верным. Я не знаю, что вы хотите здесь сделать, но это кажется подозрительным (смена местоположения сейчас без интернета, но гл. :)).

...