比较三段式软件版本号大小

      服务端接收到客户端的请求,有时候须要对低于控制版本的客户端返回不一样的结果。版本号通常是三段式的 "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;
    }
}
相关文章
相关标签/搜索