簡體   English   中英

將64位Int轉換為Char [](並返回)

[英]Convert 64bit Int to Char[] (and back)

我編程時希望將一系列big-endian(我相信,因為我在Mac上,所以int就是little-endian)字符(或uint8_ts)轉換為int64_t並返回。 這是我的代碼:

int64_t CharsToInt(uint8_t* chars) {
    return chars[0] + (chars[1] * 0x100) + (chars[2] * 0x10000) + (chars[3] * 0x1000000) + (chars[4] * 0x100000000) + (chars[5] * 0x10000000000) + (chars[6] * 0x1000000000000) + (chars[7] * 0x100000000000000);
}

void IntToChars(int64_t i, uint8_t* chars) {
    for(int k = 0; k < 8; k++) {
        chars[k] = i >> k*8;
    }
}

int main() {

    int64_t x;

    unsigned char chars[8];

    IntToChars(x, chars);

    for (int k = 0; k < 8; k++) {
        printf("%0x\n", chars[k]);
    }

    // little endian
    int64_t rv = CharsToInt(chars);

    printf("%lld\n", rv);
}

如果x為12,或者其他零或正數,則代碼工作正常,但是,如果x為負數,則該代碼將無法正常工作。

x = 12的輸出:

c
0
0
0
0
0
0
0
value: 12

x = -12的輸出:

f4
ff
ff
ff
ff
ff
ff
ff
value: -4294967308

這似乎與符號存儲和轉換的方式有關,因為我認為Intel(我在Mac上)使用2s兼容而不是普通的舊符號位。 但是,我真的不知道如何確定這是否正確,以及如何補償(最好是通過便攜式方式)。

我知道還有很多其他這樣的問題,而且我已經閱讀了這些問題(實際上大部分代碼是從他們那里獲得的),但是我仍然無法使其正常工作,所以我問了自己一個問題。

你是對的。 Intel 64和IA-32使用帶符號的2補碼表示。 請參閱《 Intel 64和IA-32體系結構軟件開發人員手冊》第4.2.1節。 因此,讀取-12的FFFFFFFFFFFFFFF4是正確的。 在2補碼表示中,負數表示為相應的正數,將所有位取反並加1:

12 = 000000000000000C -> FFFFFFFFFFFFFFF3 -> FFFFFFFFFFFFFFF4 = -12

如果我可以添加一些東西,您還應該通過以下操作將char數組轉換為uint64_t

int64_t CharsToInt(uint8_t* chars) {
    return *(int64_t*)chars;
}

經過一番摸索之后,這才是我最終的工作(我認為)。 通過使用C掩碼和乘法,通過刪除符號並在轉換后重新應用它,實際上避免了必須同時處理字節序和2s補全:

int64_t CharsToInt(uint8_t* chars) {
    // Don't modify argument
    uint8_t tmp;
    tmp = chars[0];
    bool neg = false;
    if (tmp & 0x80) {
        tmp &= 0x7f;
        neg = true;
    }

    int64_t rv = chars[7] + (chars[6] * 0x100) + (chars[5] * 0x10000) + (chars[4] * 0x1000000) + (chars[3] * 0x100000000) + (chars[2] * 0x10000000000) + (chars[1] * 0x1000000000000) + (tmp * 0x100000000000000);

    if (neg) {
        rv *= -1;
    }
    return rv;

}

void IntToChars(int64_t i, uint8_t* chars) {
    int64_t num = i;
    bool neg = false;
    if (i & 0x8000000000000000) {
        neg = true;
        num *= -1;
    }

    chars[0] = num / 0x100000000000000;
    num = num % 0x100000000000000;
    chars[1] = num / 0x1000000000000;
    num = num % 0x1000000000000;
    chars[2] = num / 0x10000000000;
    num = num % 0x10000000000;
    chars[3] = num / 0x100000000;
    num = num % 0x100000000;
    chars[4] = num / 0x1000000;
    num = num % 0x1000000;
    chars[5] = num / 0x10000;
    num = num % 0x10000;
    chars[6] = num / 0x100;
    num = num % 0x100;
    chars[7] = num;

    if (neg) {
        chars[0] += 0x80;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM