Как порядковый номер бита влияет на побитовые сдвиги и ввод-вывод файла в C? - PullRequest
6 голосов
/ 31 марта 2011

Пусть L и B - две машины. L заказать его бит из LSB (Младший значащий бит) в MSB (старший значащий бит) при порядке B от MSB до LSB. Или, другими словами, L использует Little Endian, в то время как B использует Big Endian бит - не путать с порядком байтов.

Задача 1 решена :

Мы пишем следующий код, который мы хотим переносить:

#include <stdio.h>

int main()
{
    unsigned char a = 1;
    a <<= 1;

    printf("a = %d\n", (int) a);

    return 0;
}

на L , будет напечатано 2, но что происходит на B ? Будет ли это сдвинуть 1 и напечатайте 0?.

РЕШЕНИЕ: Определение C99 в 6.5.7 говорит, что, по крайней мере, на целочисленные типы без знака, << и >> будут умножаться и делиться на 2 соответственно.

Задача 2:

Мы пишем следующий код, который мы хотим переносить:

ПРОЧИТАЙТЕ программу:

/* program READ */
#include <stdio.h>

int main()
{
    FILE* fp;
    unsigned char a;

    fp = fopen("data.dat", "rb");
    fread(&a, 1, 1, fp);
    fclose(fp);

    return 0;
}

и программа WRITE:

/* program WRITE */
#include <stdio.h>

int main()
{
    FILE* fp;
    unsigned char a = 1;

    fp = fopen("data.dat", "wb");
    fwrite(&a, 1, 1, fp);
    fclose(fp);

    return 0;
}

что произойдет, если мы запустим WRITE на L , переместим файл данных в B и запустить READ там? И если мы запустим WRITE на B , а затем ПРОЧИТАЕМ на L ?

Извините, если это FAQ. Я часами гуглил без удачи.

Ответы [ 5 ]

7 голосов
/ 31 марта 2011

Bit Endianness не влияет на данные, хранящиеся на дисках в байтах.Endianness байтов будет.

Endianness битов - это то, что имеет значение для последовательных интерфейсов, где байт отправляется по одному биту за раз, и отправителю и получателю необходимо согласовать порядок байтов.Например, порядок следования битов в устройствах SPI различен, и вам необходимо обратиться к таблице данных, прежде чем пытаться читать с устройства.

Вот что Wikipedia говорит о порядке следования битов:

Термины «порядковый номер бита» или «порядковый номер бита» редко используются, когда речь идет о представлении хранимого значения, поскольку они имеют смысл только для редких компьютерных архитектур, где каждый отдельный бит имеет уникальный адрес,Однако они используются для обозначения порядка передачи битов по последовательной среде.Чаще всего этот порядок прозрачно управляется аппаратным обеспечением и является аналогом на уровне битов little-endian (сначала младший бит), хотя существуют протоколы, которые требуют обратного порядка (например, I²C).В сети решение о порядке передачи битов принимается в самом низу канального уровня модели OSI.

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

4 голосов
/ 31 марта 2011

На самом деле не существует такой вещи, как битовая последовательность, по крайней мере, в том, что касается Си. CHAR_BIT должно быть не менее 8 в соответствии со спецификацией, поэтому доступ к любым объектам, меньшим, чем это, в значительной степени бессмыслен для стандартной программы на Си. Независимо от того, как оборудование хранит байт - сначала LSB или MSB - это никак не влияет на вашу программу. myVar & 1 возвращает правильный бит в любом случае.

Если вам нужно взаимодействовать с каким-либо последовательным интерфейсом и восстанавливать из него байты, это другая история. 'Bit-endianness' вашей собственной машины по-прежнему ни на что не влияет, но порядок битов интерфейса определенно влияет.

Теперь, что касается вашего конкретного вопроса и программы, которую вы показали. Ваши программы почти на 100% переносимы. Ни битовая, ни байтовая последовательность не влияют на них. может повлиять на них , если CHAR_BIT были разными на каждой платформе Один компьютер может записать больше данных, чем другой, или наоборот.

4 голосов
/ 31 марта 2011

number>>n и number<<n не толкают и не вытягивают биты вправо и влево. Они делят и умножают number на 2^n. Стоит отметить, что поведение этих сдвигов не определяется, если n является отрицательным или больше ширины типа данных number.

В соответствии с разделом 6.5.7 стандарта C99 :

Результатом E1 << E2 является E1-сдвинутая влево позиция E2; освобожденные биты заполнены нулями. <strong>Если E1 имеет тип без знака, значением результата будет E1 × 2 ^ E2 , уменьшенное по модулю на единицу больше максимального значения, представляемого в типе результата. Если E1 имеет тип со знаком и неотрицательное значение, а E1 × 2 ^ E2 представимо в типе результата, то это итоговое значение; в противном случае поведение не определено.

Результатом E1 >> E2 является E1-сдвинутая вправо позиция бита E2. I f E1 имеет тип без знака или, если E1 имеет тип со знаком и неотрицательное значение, значение результата является неотъемлемой частью фактора E1 / 2 ^ E2 . Если E1 имеет тип со знаком и отрицательное значение, результирующее значение определяется реализацией.

При всех заботах компилятора биты могут располагаться вертикально:)

2 голосов
/ 31 марта 2011

Смещение битов не зависит от порядка байтов.Двоичный файл ввода / вывода обычно есть, но не в вашем случае, поскольку вы пишете только один байт.

0 голосов
/ 31 марта 2011

Порядковый номер не повлияет на вас, если а) вы не прочитали что-либо из памяти, используя тип, отличный от того, для которого вы это записывали, или если вы прочитали что-либо из файла, который был написан на машине с другим порядком байтов.

т.е.

int data;
char charVal;

*data = 1;
charval = *((char *) data);  // Different result based on endianness

Или ваш второй пример, предполагая, что вы используете тип больше чем char.

...