Как правильно читать бинарные файлы? - PullRequest
0 голосов
/ 05 июня 2019

У меня проблема с тестом NIST / Diehard Binary Matrix.Речь идет о делении двоичной последовательности на матрицу 32х32 и вычислении ее ранга.После вычисления рангов мне нужно вычислить значение xi ^ 2, а затем вычислить значение p (должно быть от 0 до 1).Я получаю р-значение чрезвычайно маленьким даже в случайной последовательности.

Я пытался жестко закодировать несколько небольших примеров и правильно определить свое p-значение, хотя думаю, что моя проблема заключается в чтении двоичного файла последовательности и получении битов из него.

Это чтение из файла и преобразование в битовую последовательность.

ifstream fin("seq1.bin", ios::binary);
    fin.seekg(0, ios::end);
    int n = fin.tellg();
    unsigned int start, end;
    char *buf = new char[n];
    fin.seekg(0, ios::beg);
    fin.read(buf, n);
    n *= 8;
    bool *s = new bool[n];
    for (int i = 0; i < n / 8; i++) {
        for (int j = 7; j >= 0; j--) {
            s[(i) * 8 + 7 - j] = (bool)((buf[i] >> j) & 1);
        }
    }

Затем я формирую свою матрицу и вычисляю ее ранг

    int *ranks = new int[N];

    for (int i = 0; i < N; i++) {
        bool *arr = new bool[m*q];
        copy(s + i * m*q, s +(i * m*q) + (m * q), arr);
        ranks[i] = binary_rank(arr, m, q);
    }

Проверка наличия в рангах

int count_occurrences(int arr[], int n, int x){
    int result = 0;
    for (int i = 0; i < n; i++)
        if (x == arr[i])
            result++;
    return result;
}

Вычисление xi ^ 2 и p-значения

double calculate_xi(int fm, int fm_1, int remaining, int N) {
    double N1 = 0.2888*N;
    double N2 = 0.5776*N;
    double N3 = 0.1336*N;
    double x1 = (fm - N1)*(fm - N1) / N1;
    double x2 = (fm_1 - N2)*(fm_1 - N2) / N2;
    double x3 = (remaining - N3)*(remaining - N3) / N3;
    return x1 + x2 + x3;
}
double calculate_pvalue(double xi2) {
    return exp(-(xi2 / 2));
}

Я ожидаю p-значение между 0 и 1, но получаю 0 каждый раз.Это из-за чрезвычайно большого значения xi ^ 2, и я не смог найти то, что сделал неправильно.Не могли бы вы помочь мне сделать все правильно.

1 Ответ

0 голосов
/ 05 июня 2019

Для этой части:

for (int i = 0; i < n / 8; i++) {

    for (int j = 7; j >= 0; j--) {

        s[(i) * 8 + 7 - j] = (bool)((buf[i] >> j) & 1);
    }
 }

, когда вы добавляете элементы в массив s, похоже, что вы переключаете позицию байтов внутри каждого символа: последний бит в символе buf переходит в первый бит в символев массиве s, потому что смещение изначально равно 7, поэтому вы берете первый бит в char из buf [], но для s [] он выглядит равным 0, что приводит к замене.Это легко проверить с помощью отладчика, поскольку из кода это не так очевидно.Спасибо.

...