比較三段式軟件版本號大小

      服務端接收到客戶端的請求,有時候須要對低於控制版本的客戶端返回不一樣的結果。版本號通常是三段式的 "xx.xx.xx",一般會將版本號解析成整數數字保存在 int arr[3] 數組中,而後逐個檢查數組中的數字;最常規的作法以下:c++

int compare_version(int client_version[3], int base_version[3])
{
    if (client_version[0] > base_version[0]) {
        return 1;
    }
    else if (client_version[0] == base_version[0]) {
        if (client_version[1] > base_version[1]) {
            return 1;
        }
        else if (client_version[1] == client_version[1]) {
            if (client_version[2] > base_version[2]) {
                return 1;
            }
            else if (client_version[2] == client_version[2]) {
                return 0;
            }
            else {
                return -1;
            }
        }
        else {
            return -1;
        }
    }
    else {
        return -1;
    }
}

      上面的代碼可以正常運行,且沒有冗餘的步驟;可是比較步驟較多,if 語句層層嵌套,代碼結構較爲複雜。
      本着「更短、更快、更強」的原則,開始思考能不能將代碼優化一下。
      正常狀況下,咱們比較字符串「123」與「124」,都是從百位、十位、個位依次進行比價,就像上面的函數所作的那樣。而對於 int a = 123, int b = 124, 咱們能夠直接用 a > b、 a == b、a < b 來進行比較;因此,若是可以把版本號的三個部分合併成一個更大的變量來進行比較,那麼一步就能夠比較出版本大小了。如何把三個 int 變量合併成一個更大的整形變量呢?
      一個 int 變量佔用4個字節,32個bit;若是可以有一個 int96 的基本類型,那麼能夠這樣作:數組

int96 a,b;
a = *(int96*)client_version; //假設系統是 big-edian
b = *(int96*)base_version;
if (a > b) {
  return 1;
}
else if (a == b) {
  return 0;
}
else {
  return -1;
}

      可是C++中沒有佔用96個bit的整數類型。
      那麼能不能將三個int放在一個int中呢?函數

      考慮到市場上能夠看到的各類軟件的版本號,對於主版本號.次版本號.編譯版本號,沒見過哪一個版本號是超過100的;那麼,用10個bit(最大值1023)來表示一個版本號是足夠的;因此,三段版本號能夠分別用10個bit來表示,而後壓縮進一個32bit的int中。對於有符號的10個bit,其能表示的數字範圍爲 -1024 ~ 1023,足夠咱們使用的了。
      以下兩個方法都可:優化

方法一code

int compare_version(int client_version[3], int base_version[3])
{
    int client = (client_version[0] << 20) | (client_version[1] << 10) | clien_version[2];
    int base = (base_version[0] << 20) | (base_version[1] << 10) | base_version[2];
    if (client > base) {
        return 1;
    }
    else if (client == base) {
        return 0;
    }
    else {
        return -1;
    }
}

方法二字符串

int compare_version(int client_version[3], int base_version[3])
{
    int diff = 0;
    diff += (client_version[0] - base_version[0]) << 20;
    diff += (client_version[1] - base_version[1]) << 10;
    diff += (client_version[2] - base_version[2]);
    if (diff > 0) {
        return 1;
    }
    else if (diff == 0) {
        return 0;
    }
    else {
        return -1;
    }
}
相關文章
相關標籤/搜索