двухбайтовый обмен - PullRequest
       3

двухбайтовый обмен

0 голосов
/ 06 декабря 2010

Есть некоторые дискуссии по тому же вопросу, но я хотел бы задать еще несколько,

1) Насколько переносим код ниже для двухбайтовой замены

int ReadDouble(FILE *fptr,double *n)
{
   unsigned char *cptr,tmp;

   if (fread(n,8,1,fptr) != 1)
      return(FALSE);

   cptr = (unsigned char *)n;
   tmp = cptr[0];
   cptr[0] = cptr[7];
   cptr[7] = tmp;
   tmp = cptr[1];
   cptr[1] = cptr[6];
   cptr[6] = tmp;
   tmp = cptr[2];
   cptr[2] = cptr[5];
   cptr[5] =tmp;
   tmp = cptr[3];
   cptr[3] = cptr[4];
   cptr[4] = tmp;

   return(TRUE);
} 

2) Должен ли я сохранить 3 важные части числа с плавающей запятой, знаковый бит, мантиссу, экспоненту как целые числа, а затем попытаться каким-то образом ими манипулировать.

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

Так что после некоторых комментариев это должно более или менее сделать это портативным способом, верно? Извините за указатели файла C ...

double_t ReadDouble(ifstream& source) {
  // read 
  char buf[sizeof(double_t)];
  source.read(buf, sizeof(double_t));
  // reverse and return
  reverse( buf, buf+sizeof(double_t) );
  return *(reinterpret_cast<double_t*>(buf));
}

Best, Умут

Ответы [ 2 ]

2 голосов
/ 06 декабря 2010

Это не так просто.Тот факт, что архитектура является целым порядком байтов для целых чисел, не означает, что она является порядком байтов для чисел с плавающей запятой.Я слышал о платформах, которые хранят целые числа с прямым порядком байтов и плавающие с прямым порядком байтов.Итак, сначала вы должны выяснить, каково реальное представление памяти в double на вашей исходной платформе.

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

int ReadDouble(FILE* f, double* n) {
  unsigned char* nbytes = reinterpret_cast<unsigned char*>(n);
  unsigned char buf[sizeof(double)];
  if (fread(buf, sizeof(double), 1, f) != 1) return FALSE;

  for (int i = 0; i < sizeof(double); ++i) {
    nbytes[i] = buf[sizeof(double)-1-i];
  }
  return TRUE;
}

Значительно меньше кода, даже если вы решили вручную развернуть цикл.

1 голос
/ 06 декабря 2010

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

Один простой способ проверить это посмотреть на представление битов известной константы.

...