#include<stdio.h>
#include "random.h"
static char tab[] = "0123456789abcdef";
char * toh(char *p, int val)
{
if(val > 0){
p = toh(p, val >> 4);
*p++ = tab[val & 0xf];
}
return p;
}
// 递归写法
void tohex1(char *buf, int val)
{
char *p = toh(buf, val);
if(p == buf) *p++ = '0';
*p = 0;
}
// 位移写法
void tohex2(char *s, int val)
{
int i = 28;
//for(; i>0 && ((val>>i) & 0xf) == 0; i-=4);
for(; i >=0; i-=4)
*s++ = tab[(val>>i) & 0xf];
*s = 0;
}
// 位移写法的改进版
void tohex3(char *s, int val)
{
for(int i = 3; i >=0; --i){
int t = val >>(i << 3);
*s++ = tab[(t>>4)& 0xf];
*s++ = tab[t& 0xf];
}
*s = 0;
}
// 常见写法,使用反转
void tohex4(char *s, int val)
{
char *p = s;
do{
*s++ = tab[val&0xf];
}while(val >>=4);
*s = 0;
while(p<s-1){//反转
char t = *p;
*p++ = *--s;
*s = t;
}
}
union Hex
{
char c[4];
int val;
};
// 联合直接转换法
void tohex5(char *s, int val)
{
Hex h;
h.val = val;
*s++ = tab[(h.c[3]>>4)&0xf];
*s++ = tab[h.c[3] & 0xf];
*s++ = tab[(h.c[2]>>4)&0xf];
*s++ = tab[h.c[2] & 0xf];
*s++ = tab[(h.c[1]>>4)&0xf];
*s++ = tab[h.c[1] & 0xf];
*s++ = tab[(h.c[0]>>4)&0xf];
*s++ = tab[h.c[0] & 0xf];
*s = 0;
}
//测试代码:
int main()
{
char buf[5][10];
int i, val = 0x1234bcde, N = 10000000;
double time1;
Clock.start();
for(i = 0; i < N; ++i)
tohex1(buf[0], val);
time1=Clock.elapse();
printf("hex1 :%.3f\n", time1);
Clock.start();
for(i = 0; i < N; ++i)
tohex2(buf[1], val);
time1=Clock.elapse();
printf("hex2 :%.3f\n", time1);
Clock.start();
for(i = 0; i < N; ++i)
tohex3(buf[2], val);
time1=Clock.elapse();
printf("hex3 :%.3f\n", time1);
Clock.start();
for(i = 0; i < N; ++i)
tohex4(buf[3], val);
time1=Clock.elapse();
printf("hex4 :%.3f\n", time1);
Clock.start();
for(i = 0; i < N; ++i)
tohex5(buf[4], val);
time1=Clock.elapse();
printf("hex5 :%.3f\n", time1);
puts(buf[0]);
puts(buf[1]);
puts(buf[2]);
puts(buf[3]);
puts(buf[4]);
}
运行结果:

由此可见,递归写法最慢,有趣的是算法3, 循环次数减半,用时也会减半,算法5由于没有循环,所以速度居然达到最快,这种将循环展开为直接代码输出,可有效提升代码运行速度,这种方式在阅读mpg123的原代码也经看到。算法2-5适合不同的应用场景,记录于此,仅供参考。
#include "random.h"
static char tab[] = "0123456789abcdef";
char * toh(char *p, int val)
{
if(val > 0){
p = toh(p, val >> 4);
*p++ = tab[val & 0xf];
}
return p;
}
// 递归写法
void tohex1(char *buf, int val)
{
char *p = toh(buf, val);
if(p == buf) *p++ = '0';
*p = 0;
}
// 位移写法
void tohex2(char *s, int val)
{
int i = 28;
//for(; i>0 && ((val>>i) & 0xf) == 0; i-=4);
for(; i >=0; i-=4)
*s++ = tab[(val>>i) & 0xf];
*s = 0;
}
// 位移写法的改进版
void tohex3(char *s, int val)
{
for(int i = 3; i >=0; --i){
int t = val >>(i << 3);
*s++ = tab[(t>>4)& 0xf];
*s++ = tab[t& 0xf];
}
*s = 0;
}
// 常见写法,使用反转
void tohex4(char *s, int val)
{
char *p = s;
do{
*s++ = tab[val&0xf];
}while(val >>=4);
*s = 0;
while(p<s-1){//反转
char t = *p;
*p++ = *--s;
*s = t;
}
}
union Hex
{
char c[4];
int val;
};
// 联合直接转换法
void tohex5(char *s, int val)
{
Hex h;
h.val = val;
*s++ = tab[(h.c[3]>>4)&0xf];
*s++ = tab[h.c[3] & 0xf];
*s++ = tab[(h.c[2]>>4)&0xf];
*s++ = tab[h.c[2] & 0xf];
*s++ = tab[(h.c[1]>>4)&0xf];
*s++ = tab[h.c[1] & 0xf];
*s++ = tab[(h.c[0]>>4)&0xf];
*s++ = tab[h.c[0] & 0xf];
*s = 0;
}
//测试代码:
int main()
{
char buf[5][10];
int i, val = 0x1234bcde, N = 10000000;
double time1;
Clock.start();
for(i = 0; i < N; ++i)
tohex1(buf[0], val);
time1=Clock.elapse();
printf("hex1 :%.3f\n", time1);
Clock.start();
for(i = 0; i < N; ++i)
tohex2(buf[1], val);
time1=Clock.elapse();
printf("hex2 :%.3f\n", time1);
Clock.start();
for(i = 0; i < N; ++i)
tohex3(buf[2], val);
time1=Clock.elapse();
printf("hex3 :%.3f\n", time1);
Clock.start();
for(i = 0; i < N; ++i)
tohex4(buf[3], val);
time1=Clock.elapse();
printf("hex4 :%.3f\n", time1);
Clock.start();
for(i = 0; i < N; ++i)
tohex5(buf[4], val);
time1=Clock.elapse();
printf("hex5 :%.3f\n", time1);
puts(buf[0]);
puts(buf[1]);
puts(buf[2]);
puts(buf[3]);
puts(buf[4]);
}
运行结果:

由此可见,递归写法最慢,有趣的是算法3, 循环次数减半,用时也会减半,算法5由于没有循环,所以速度居然达到最快,这种将循环展开为直接代码输出,可有效提升代码运行速度,这种方式在阅读mpg123的原代码也经看到。算法2-5适合不同的应用场景,记录于此,仅供参考。