当谈到十六进制时,我的大脑放屁了很多。有些人是灵巧的,有些人只是简单的右手......好吧,有点像这样,我认为我非常基础。
无论如何......我正在尝试使一些固件更有效率。我们有一个功能,它根据通过CANBUS获得的一些十六进制数据来计算车辆的速度。现在我正在将它转换为浮点数,所以我可以把它包裹起来但是我想知道如果我们把它放在整数格式中我们是否会使用更少的ROM空间?这可以做到而不会失去准确性吗?现在我的花车精确到1/16千瓦时。我知道这个功能看起来很简单,但是每秒运行数百次就会让它变得有点麻烦。
首先,这是一些示例数据:
[06] [3c] ...... [06] [3a] ...... [06] [3b] ...... [06] [46] ...... [06] [3b] ......
由于与速度无关,我已将其他6个字节留下。左边的字节我们称之为speed_a,右边的字节是speed_b。这是转换函数:
float calculateSpeed()
{
float speed;
speed = ( ( float )speed_a * 256.0 + speed_b ) / 16.0;
return speed;
}
所以上面的数据会转换为:
99.7500 99.6250 99.6875 100.3750 99.6875
并且确实以kph准确反映了车辆的真实速度。对于我们的应用,我们并不关心真正的速度是什么,因为一切都是相对的。只要我们不失去决心,我们就会感到高兴。我想过只保留INT形式的所有东西,但是当你除以16时它只是截断。
我对大多数事情都不是白痴......但我是base2的白痴。
Lil'帮忙吗?感谢。
答案 0 :(得分:8)
根本不要除以16.0。您仍然可以比较,排序,添加或减去速度。
答案 1 :(得分:3)
整数总是比浮点数快。而不是使用浮点数来表示kph,而是使用整数来表示kph的1/16。
然后您的代码变为:
int calculateSpeed() {
return speed_a * 256 + speed_b
}
只有当你需要显示给用户的值时,我才会转换回浮点数:
int s = calculateSpeed();
printf ("Speed = %f\n", ((float)(s))/16.0);
取决于你的编译器的智能程度,以及你的CPU有多好(我可能错了,但这听起来像一个嵌入式系统),行:
return (speed_a << 8) + speed_b
可能会更快。
答案 2 :(得分:2)
您可以使用0.01的比例。然后整数9969表示99.69kph。这将避免基础2的复杂化。
0.01比分辨率0.0666好六倍。两倍的好就足够了。然后,您可以在每次测量时使用2个字节,最多可以表示327 kph。
如果需要除以100(例如输出),那么有approximate, but fast division by a constant的方法(例如100)。
答案 3 :(得分:1)
如果根据您描述的要求使用fixed point math,您将节省给定精度的空间,因为您只需使用您需要的位数来存储小数部分。
但是,大多数编译器将浮点数存储为32位值,而我见过的大多数定点数学库也使用32位作为存储。除非您可以使用16位定点数表示所需的数字范围(整数和小数部分),否则float和(32位)int之间不存在存储差异。
底线除非您想要处理16位定点数,否则int和float可能会在您的系统上使用相同数量的存储空间。
答案 4 :(得分:1)
你可以选择:
int calculateSpeed () {
int speed;
speed = ( (speed_a * 256 ) + speed_b );
return speed;
}
我只是基本上删除了div部分,因为你不需要它:int至少是32位 - 而你有2个字节是16位一起。
答案 5 :(得分:0)
史蒂芬,
整数除法只给出整数结果。实(浮点)除法给出浮点结果。
在您的情况下,您可以将其存储为米,或厘米甚至每秒微米。然后当你进行适当比例的整数除法时,你不会关心截断,你可以将转换推迟到Kph,直到打印/显示结果(或导出到任何期望这些单位的东西等)。
顺便提一下,另一种旧方法是执行(整数)除法和模数运算对...将结果存储为商/余数对,直到打印/显示/导出为止。已经使用这种“缩放整数算术”模型实现了整个数学例程库......与浮点计算相比,它可以提供显着的性能和精度优势。
答案 6 :(得分:0)
是否允许丢失数据?如果不是,你不能对这个小数做多少......否则:
int speed = ((float_a << 8) | float_b) >> 4;
将两个char
设为short
并删除最后4位(与将其除以16得到整数部分相同)。
使用按位运算时,你也可以获得性能提升比使用乘法/除法快一点(尽管这种增益对于实际的计算机来说几乎无关紧要)。
答案 7 :(得分:0)
如果您只想转换为 display 的十进制数,而不使用浮点运算,如果以km / h的十六分之一测量speed
,则可以执行以下操作:
printf("%d.%04d", speed / 16, 10000 * (speed % 16) / 16);
在嵌入式环境中,如果不需要链接任何浮点算术库,您当然可以保存ROM空间的批次。听起来你可能不希望在应用程序中消除浮点的所有使用。 (更不用说还避免使用printf()
,但这是另一个故事。)
如果您的测量设备提供的精度不超过十六分之一,则显示两位小数以上是没有意义的。上述示例的修改以考虑该格式是留给读者的练习。