双字节交换

时间:2010-12-06 14:47:24

标签: c++ binaryfiles

关于同一个问题有一些讨论,但我想再问一些,

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));
}

最佳, 了Umut

2 个答案:

答案 0 :(得分:2)

这并不容易。仅仅因为一个体系结构是整数的大端并不意味着它是浮点数的大端。我听说过存储整数big-endian和浮动little-endian的平台。 首先,您应该了解源平台上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 :(得分:1)

这不可移动,因为您没有检查机器的顺序与文件中的预期顺序。如果机器与文件匹配,那么您将字节交换到错误的顺序。

一种简单的检查方法是查看已知常量的位表示。