2010-12-06 52 views
0

大約有同樣的問題,一些討論,但我想問多一些,雙字節交換

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

+0

你知道輸入將永遠是big-endian嗎? – 2010-12-06 14:53:14

+0

是的,顯然商業軟件以big-endian生成二進制文件。 – 2010-12-06 14:55:37

回答

2

這不是這麼簡單。僅僅因爲架構是整數的大端並不意味着它是浮點數的大端。我聽說過存儲整數大平臺並且浮點小平臺的平臺。 所以首先你應該發現你的源代碼平臺上的實際內存表示是雙倍的。

至於交換本身,它是低效的,太多的代碼。額外的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

這不是可移植的,因爲您沒有檢查您的機器的順序與文件中的預期順序。如果機器與文件匹配,那麼您將交換錯誤的順序的字節。

一個簡單的方法來檢查是看一個已知常數的位表示。