嵌入式系统单精度与双精度浮点运算
开发平台
单片机——STM32F407ZGT6
软件——keil
代码分析
简单的LED闪烁功能实现代码可以如下所示:
LED_Toggle();
int i=0;
while(i<100000)
i+=1;
1.使用float进行计数
循环部分代码如下:
float i=0;
while(i<50000.0)
i+=0.5;
上面的代码在实际编译时会报出warning:#1035-D: single-precision operand implicitly converted to double-precision。这个warning的产生是由于C语言的类型转换机制所导致。为了防止精度的损失,在进行不同精度的运算时,遵循下面的转换过程。
C语言类型转换C语言默认代码中的0.5精度为双精度,因此在计算时,将i进行了精度转换。
2.显示指定float类型
循环部分代码如下:
while(i<50000.0f)
i+=0.5f;
此时,之前编译产生的warning会消失。程序也能正常运行。
3.区别
首先,使用keil产生的code大小不一样,比较如下:
隐式数据转换:Program Size: Code=3556 RO-data=440 RW-data=12 ZI-data=1028
显示数据类型:Program Size: Code=2724 RO-data=440 RW-data=12 ZI-data=1028
下图是keil产生的上面两种方法的汇编文件比较,左边的是没有指定数据类型的代码,右边是显示指定数据表示方法的代码。
通过比较可以看出,默认的精度转换计算过程中,会先进行一个_aeabi_f2d的函数进行精度转换,然后进行双精度的加法。
而在右侧的计算过程中,由于STM32F407中的Cortex-M4自带FPU支持单精度浮点计算,可以直接使用浮点指令来完成计算。
两段代码实际运行的速度比较,据目测观察和实验,左侧的代码快了10倍以上。右侧的代码在数据精度的损失上很小。