zoukankan      html  css  js  c++  java
  • 比较三段式软件版本号大小

          服务端接收到客户端的请求,有时候需要对低于控制版本的客户端返回不同的结果。版本号一般是三段式的 "xx.xx.xx",通常会将版本号解析成整数数字保存在 int arr[3] 数组中,然后逐个检查数组中的数字;最常规的做法如下:

    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,其能表示的数字范围为 -512 ~ 511,足够我们使用的了。
          如下两个方法均可:

    方法一

    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;
        }
    }
    
  • 相关阅读:
    MSDN2010安装及使用(MSDN Library)[转]
    单元测试那些事
    Nhibernate Profiler安装中的问题
    ztree的动态添加
    事件与委托
    linux ls dir
    学习技术资料的思路
    linux目录结构
    是否需要深入了解java平台
    工作中心的改变
  • 原文地址:https://www.cnblogs.com/dongling/p/10686448.html
Copyright © 2011-2022 走看看