当前位置:C++技术网 > 精选软件 > 万能进制漂移的数值转换函数分析和代码实现

万能进制漂移的数值转换函数分析和代码实现

更新时间:2017-03-24 18:39:48浏览次数:1+次

    我们在编程中,一般都用字符串来存储时间,如“2017-03-24 18:07:00”。这样一个字符串占用了20个字节。在网络传输时,有点不划算。所以我们在项目中使用了一种压缩格式,使用BCD码存储时间。这样,我们只需要7个字节就可以完全存储。最后一个字节是多余的,用一个字节填充。
    如何实现这样的压缩存储格式呢?什么BCD码的,听起来好复杂的样子。那么我来稍微讲讲,你就明白了。
    我们将时间约定为xxxx-xx-xx-xx-xx-xx,分别为年-月-日-时-分-秒。除了年外,其他都是两个字符的格式,不足在前面填零。所以,上面的时间可以表示为2017-03-24-18-07-00。我们只需要得到字面上的这个时间的含义就行了,存储方式都无所谓。所以我们就用数字来存储时间,然后再压缩一下,就可以表示时间了。
    我们将2017-03-24-18-07-00分别用0x20 0x17 0x03 0x24 0x18 0x07 0x00,七个字节就可以得到这个时间值了。这样就将字符串格式的时间变成了数值格式的时间。
    我们来观察一下特点。数字形式的格式,在字面上和字符串的一样,而且数字是十六进制的。一个字节表示的数字,代替了字符串里两个字符即两个字节,也就压缩了一大半的存储空间。而且,我们在编程时不需要在数字和字符之间转换时间,这样就变得更加方便了。
    我们现在想想应用场景:我们从系统中获取时间,得到了一个时间结构体,然后我们需要将这个时间结构体的值分布对应存储到8字节的数组中。然后在读取时间时,我们从这个数组中分别读出各个字节存储的值,就可以获取时间了。
    从数组获取时间,我们只需要将数组的值按照十六进制格式化,就可以得到正确的时间字符串了。但是如果你想从十六进制显示的时间值直接转成十进制显示的时间值,就需要做点工作了。不要说直接赋值,这是不行的。比如:
int day = arr[3];//0x24
    这样month得到的值并不是24,而是36。数值在赋值的时候,只是按照存储的值赋值,而不会做进制转换的。进制只是人为看到的一种显示格式,并不是存储格式。
    正确的做法是将十六进制显示的值变成十进制存储的值。也就是说,我们要将0x24直接变成24。然后我们可以得到正确的十进制时间值了。这个并不是通常理解的进制转换。我们可以理解为进制值漂移,直接将字面数值漂移到另外一个进制。这样的话,我们是需要改变这个值本身的值的,从而实现在另一个进制中显示同样的数值。
    以上有点小绕,请仔细区分进制转换和进制值漂移。
进制转换:11(十进制) <- 0x0B(十六进制)【存储的数值没有变】
进制漂移:11(十进制) <- 0x11(十六进制)【存储的数值发生变化】
    那么我们将存储的arr[3]的日(0x24)要直接漂移为十进制的24,就得到了正确的日期。你可以自己试着实现一下。方法就是基于进制原理来改变数值,最终就得到了显示上的一样的数值。
    那么我们知道了获取存储的BCD时间值,那么我们怎么存储BCD时间值呢?我们如何将系统得到的十进制的时间,存储到BCD时间数组里呢?与获取时间恰好相反。我们只是主动将十进制的时间值,漂移到十六进制存进去就行了。
进制转换:11(十进制) -> 0x0B(十六进制)【存储的数值没有变】
进制漂移:11(十进制) -> 0x11(十六进制)【存储的数值发生变化】
    那么下面我就分享下我写好的万能进制漂移数值转换函数的代码:
int basetobase(int dig,int dst_base,int src_base)
{
 //dig被转换的数,dst_base目标进制,src_base源进制
 int tmp=0;
 if (src_base<=dst_base)
 {
 tmp = dig/src_base*dst_base+dig%src_base;
 }
 else
 {
 tmp = dig/dst_base*src_base+dig%dst_base;
 }
 return tmp;
}

    下面是完整的测试代码:
#include "stdio.h"
int basetobase(int dig,int dst_base,int src_base)
{
 //dig被转换的数,dst_base目标进制,src_base源进制
 int tmp=0;
 if (src_base<=dst_base)
 {
 tmp = dig/src_base*dst_base+dig%src_base;
 }
 else
 {
 tmp = dig/dst_base*src_base+dig%dst_base;
 }
 return tmp;
}

int main()
{
 int i = basetobase(23,4,10);
 printf("%d",i);
 return 0;
}