您已经用以下声明回答了您自己的问题:
范围将是 2-500 (cm) 之间的值,
以厘米(甚至毫米)为单位,而不是米单位。
也就是说,您不需要浮点硬件来进行浮点数学运算;编译器将支持"soft"浮点并生成执行浮点运算的代码 - 它会比硬件浮点或整数运算慢,但这在您的应用程序中可能不是问题。
尽管如此,即使有硬件支持,也有很多理由避免使用浮点,而且听起来您的 FP 案例并不是特别引人注目,但如果没有看到您的代码和具体示例,很难说清楚。在 32 年的嵌入式系统开发生涯中,我很少使用 FP,即使是在三角函数、对数函数、开方函数和数字信号处理中也是如此。
通用方法是使用固定点推介会。我之前建议使用厘米是一个例子小数定点,但为了提高效率,您应该使用二进制定点。例如,您可能以 1/1024 米为单位表示距离(精度 > 1 毫米)。由于定点是二进制的,因此所有必要的重新缩放都可以通过移位完成,而不是通过更昂贵的乘法/除法运算来完成。
例如,假设您有一个 8 位传感器,可生成对应于 0 到 0.5 米实际距离的线性输出 0 到 255。
#define Q10_SHIFT = 10 ; // 10 bits fractional (1/1024)
typedef int q10_t ;
#define ONE_METRE = (1 << Q10_SHIFT)
#define SENSOR_MAX = 255
#define RANGE_MAX = (ONE_METRE/2)
q10_t distance = read_sensor() * RANGE_MAX / SENSOR_MAX ;
distance
采用 Q10 定点表示法。对此类进行加法和减法是正常的整数算术,乘法和除法需要缩放:
int q10_add( q10_t a, q10_t b )
{
return a + b ;
}
int q10_sub( q10_t a, q10_t b )
{
return a - b ;
}
int q10_mul( q10_t a, q10_t b )
{
return (a * b) >> Q10_SHIFT ;
}
int q10_div( q10_t a, q10_t b )
{
return (a << Q10_SHIFT) / b ;
}
当然,您可能希望能够混合类型并说乘以q10_t
by an int
- 为定点提供全面的库可能会变得复杂。就我个人而言,我使用 C++,其中有类、函数重载和运算符重载来支持更自然的代码。但是,除非您的代码具有大量通用定点数学,否则临时编写特定定点运算可能会更简单。
以您提供的一个例子为例:
double voltage_difference_new = ((memval3_new - memval4_new)*3.3/4096);
使用毫伏可以轻松去除浮点:
int voltage_difference_new_mv = ((memval3_new - memval4_new) * 3300) /4096 ;
那么问题可能会变成以下之一推介会。例如,如果您必须呈现或报告中的值volts给用户。在这种情况下:
int volt_fract = abs(voltage_difference_new_mv % 1000) ;
int volt_whole = voltage_difference_new_mv / 1000 ;
printf( "%d.%04d", volt_whole, volt_fract ) ;