在实际项目中,我们不可避免的遇到需要将整数(浮点数)转换为字符串输出(保存为文件或者显示打印)。这是一个很常见的算法,标准C库甚至提供了诸如itoa,ltoa,之类的函数供大家调用。但是,在一些特殊场合,比如对功耗要求比较苛刻的场合,则对转换速度提出了要求。在单片机应用中,很多mcu没有除法器,和除法指令,我们就得变通一下。
1. 浮点数转字符串
我们知道,在单片机中,浮点运算是比较费时的运算。我们就可以根据自己的精度要求,先将浮点数转换为整数,在进行整数运算,则会节约不少运算时间。比如我们在数据采集存储过程中,只需要保留小数点后面三位。那么,我们对需要转换的浮点数乘以1000,得到整数。
float f= 417.123; int it = 0; it = (int)(f*1000);
2. 整数转换为字符串
一般情况下,我们为了代码的简洁直观,我们会采用如下形式.然后将得到的字符串颠倒一下次序就可以了,因为是从低位往高位计算的。
while(val!=0) { buf[i++] = ‘0’+ val%10; val= val/10; }
但是,这个方法,每得到一位需要两次除法运算。故,我们改进一下,
while(val!=0) { tmp = val/10; buf[i++] = '0'+ val - (val<<3) - (val<<1); val = tmp; }
这样,用几次移位和加减法,代替一次除法,效率就得到了很大的提升。
如果之前是浮点数转整数,再进行转化的,需要记住小数点的位置。
甚至,在某些场合,我们是能预先知道我们这个整数的最大值(这种是可能的,因为对功耗要求极为苛刻的场合,大多都是数据采集系统),也就是数字的位数,我可以用减法来代替除法。据说,很多MCU都是这样干的。假如,我的应用中,数据最大值不会超过999999,那么用空间换时间的写法如下,
先定义一个函数,该函数用于获取s的最高位,t指明了最高位是在哪一位。比如,s小于1000,那么t=100。
u8 func(u32 *s, u32 t) { u8 i = ‘0’; while(*s>=t) { i++; *s -= t; } return i ; }
接下来可以得到字符串。再特别说明,我预先知道val不会大于999999.
buf[1]= func(&val, 100000); buf[2]= func(&val, 10000); buf[3]= func(&val, 1000); buf[4]= func(&val, 100); buf[5]= func(&val, 10); buf[6]= '0' + val;
时间: 2024-09-30 21:44:20