2016-03-08 248 views
1

的dataFile.bin是具有6个字节记录的二进制文件。第3个 字节每条记录都包含纬度和最后3个字节包含 经度。每24位值表示弧度乘以 0X1FFFFF转换为32位整数24位整数(2S补码)在C++

这是我一直在工作的任务。我还没有做过C++中的年,所以它把我方式的时间比我想象的还要-_-。围绕谷歌搜索后,我看到这个algorthim这对我有意义。

int interpret24bitAsInt32(byte[] byteArray) {  
int newInt = ( 
    ((0xFF & byteArray[0]) << 16) | 
    ((0xFF & byteArray[1]) << 8) | 
    (0xFF & byteArray[2]) 
    ); 
if ((newInt & 0x00800000) > 0) { 
    newInt |= 0xFF000000; 
} else { 
    newInt &= 0x00FFFFFF; 
} 
return newInt; 
} 

的问题是语法问题我限制被其他家伙编程这种方式工作。我不了解如何将CHAR“数据”存储到INT中。如果“数据”是一个数组,它会更有意义吗?由于它接收24个存储在BYTE中的信息整数。

double BinaryFile::from24bitToDouble(char *data) { 
    int32_t iValue; 

    // **************************** 
    // Start code implementation 
    // Task: Fill iValue with the 24bit integer located at data. 
    // The first byte is the LSB. 
    // **************************** 
//iValue += 
    // **************************** 
    // End code implementation 
    // **************************** 
    return static_cast<double>(iValue)/FACTOR; 
} 

bool BinaryFile::readNext(DataRecord &record) 
{ 
    const size_t RECORD_SIZE = 6; 
    char buffer[RECORD_SIZE]; 
    m_ifs.read(buffer,RECORD_SIZE); 
    if (m_ifs) { 
     record.latitude = toDegrees(from24bitToDouble(&buffer[0])); 
     record.longitude = toDegrees(from24bitToDouble(&buffer[3])); 
     return true; 
    } 
    return false; 
} 

double BinaryFile::toDegrees(double radians) const 
{ 
    static const double PI = 3.1415926535897932384626433832795; 
    return radians * 180.0/PI; 
} 

我明白任何帮助,甚至如果你不理解的线索或提示将帮助我很多提示。我只需要与某人交谈。

回答

5

我不理解我怎么能CHAR“数据”存储到INT。

由于char是一种数字类型,所以将它们组合成一个单一的int没有问题。

由于信息接收其24点的整数存储到BYTE

它是24位,而不是字节,因此只有三个需要被合并整数值。

产生相同的结果,而无需使用条件语句更简单的方法如下:

int interpret24bitAsInt32(byte[] byteArray) {  
    return ( 
     (byteArray[0] << 24) 
    | (byteArray[1] << 16) 
    | (byteArray[2] << 8) 
    ) >> 8; 
} 

的想法是作为输入提供的三个字节存储到三个字节的四个字节的int,然后由一个字节移位下来。这样程序会自动签名扩展你的号码,避免条件执行。

注意:此代码不可移植,因为它假定为32位整数大小。为了使便携使用<cstdint>类型:

int32_t interpret24bitAsInt32(int8_t[] byteArray) { 
    return ( 
     (byteArray[0] << 24) 
    | (byteArray[1] << 16) 
    | (byteArray[2] << 8) 
    ) >> 8; 
} 

它还假定的24位数字的最显著字节存储在byteArray初始元素,然后是中间单元,最后至少显著字节。

+1

@SergeyA哎呀,我确实复制粘贴超过了必要的。谢谢! – dasblinkenlight

0

当无符号字符浇铸为int高阶位用0填充的

当符号字符被浇铸的铸造int,则符号位被延长。 即:

int x; 
char y; 
unsigned char z; 
y=0xFF 
z=0xFF 
x=y; 
/*x will be 0xFFFFFFFF*/ 
x=z; 
/*x will be 0x000000FF*/ 

所以,你的算法,使用0xFF的作为掩模,移除C”符号扩展,即

0xFF == 0x000000FF 
0xABCDEF10 & 0x000000FF == 0x00000010 

然后使用移位和逻辑ANDS把位各得其所。

最后检查最高有效位(newInt & 0x00800000) > 0以决定是否用0或1完成最高字节。