2010-02-14 49 views
2

我讀的是GNU PDF庫的源碼,尤其是它們的64位整數實現。他們將64位整數定義爲兩個32位整數的結構 - 高位int是有符號的,低位int是無符號的。以下是頭文件中的相關代碼:64位二進制補碼形式的負整數

/*Definition of internal structure of the pdf_i64_t type*/ 
struct pdf_i64_s 
{ 
    pdf_i32_t high; 
    pdf_u32_t low; 
}; 

typedef struct pdf_i64_s pdf_i64_t; 

根據體系結構手冊,負數用二進制補碼形式表示。我有一個關於這個功能的一個疑問,但:

[從pdf-types.c代碼]

void pdf_i64_assign_quick (pdf_i64_t *bignum, 
         const pdf_i32_t value, 
        pdf_status_t *p_status) 
{ 
    ASSIGN_SAFE(p_status, PDF_OK); 

    if (bignum != NULL) 
    { 
     if (value < 0) 
     { 
      bignum->high = 0xFFFFFFFF; 
     } 
     else 
     { 
      bignum->high = 0; 
     } 
     bignum->low = value; 
    } 
    else 
    { 
     ASSIGN_SAFE(p_status, PDF_ERROR); 
    } 
} 

從我讀,得到一個數字的二進制補碼,您需要反轉所有位並添加1〜結果。在上述函數中,對於值< 0,它們只將高位設置爲0xFFFFFFFF,但根本不改變低位。 「價值」的位不應該反過來,然後再加上1?有人可以解釋這個嗎?

謝謝。

+0

應該指出,這段代碼有未定義的行爲,將有符號整數類型範圍以外的值賦給該類型的變量。相反,它應該分配'-1'。 – 2010-09-21 02:52:03

回答

5

你會注意到,value已經一個有符號的32位整數 - 如果它是負數,它已被適當倒置。所有需要做的是符號擴展。

0

它說該值是一個32位的int ...值應該已經在二進制補碼形式,從而無需改變

3

我想你混淆了一些東西 - 否定了一些在二進制補碼錶示法中,您翻轉所有位並添加一個。

雖然這裏沒有否定。這是存儲一個值,並做符號擴展 - 最高位必須擴展到高32位。這是發生了什麼,因爲輸入已經被簽名,是二進制補碼輸入。

1

Anon已經回答了這個問題,我只是想發佈一個輕微的優化,完成同樣的事情沒有分支。

void pdf_i64_assign_quick (pdf_i64_t *bignum, 
         const pdf_i32_t value, 
        pdf_status_t *p_status) 
{ 
    ASSIGN_SAFE(p_status, PDF_OK); 

    if (bignum != NULL) 
    { 
     bignum->high = (value >= 0) - 1; 
     bignum->low = value; 
    } 
    else 
    { 
     ASSIGN_SAFE(p_status, PDF_ERROR); 
    } 
} 

0xffffffff的是32位的十六進制爲-1和(值> = 0)的計算結果爲1或0,所以它也設置高到0xFFFFFFFF爲value負值和爲0的正值。