基于STM32的浮点数运算出错详解

浮点数分离成整数和小数

因为十进制运算的底层是2进制运算,有些浮点数并不能完全用二进制表示,一定会有误差,误差在小数点最后几位。

比如下面这个例子,想要分别取出整数部分和小数部分。浮点数26.90想要得到的理想输出结果是 整数26和整数90 两个数。

float value = 26.90;
unsigned int  value_integer; //存放整数 26
unsigned char value_decimal; //存放小数(实际放大了100倍) 90
float decimal_old;           //存放小数(未乘以100)
float decimal_new;           //存放小数(乘以100)

value_integer = (unsigned int)value;        //取整数 26
decimal_old = value - value_integer;        //取小数(未乘以100)
decimal_new = decimal * 100.0f;             //取小数(乘以100)
value_decimal = (unsigned char)decimal_new; //强制类型转换,取出小数部分 90

printf("value = %d",value);
printf("value_integer = %d",value_integer); //打印整数部分
printf("decimal_old = %f",decimal_old);     //打印小数部分(未乘以100)
printf("decimal_new = %f",decimal_new);     //打印小数部分(乘以100)
printf("value_decimal = %d",value_decimal); //打印左移两位小数点后的小数部分,即实际放大了100倍

经过实验仿真后,得到的输出结果如下

value = 26.900000
value_integer = 26
decimal_old = 0.900000
decimal_new = 89.999962
value_decimal = 89

会发现前后结果不一致,得不到理想的效果:整数26和整数90。因此,需要对浮点数进行一定的处理。

这里将完整的操作封装成一个函数,供大家使用。

//函数功能:将浮点数分离成 整数部分和小数部分
//value:待分离的浮点数
//value_integer:指针,用于存放整数部分
//value_decimal:指针,用于存放小数部分
static void Separate_IntegerAndDecimal(float value,	unsigned int  *value_integer, unsigned char *value_decimal)
{
	float decimal;
	
	*value_integer = (unsigned int)value; //取出整数部分
	decimal = value - (*value_integer); //小数部分(未处理)
	*value_decimal = (unsigned char)((decimal * 100.00f) + 0.5f); //取出小数部分(已处理)
}

实验仿真后得到理想的实验结果,分离出整数26和整数90。

这里特别注意:

浮点数计算一直计算下去,误差会越大,所以value每次传入的值都是新的(每次传入一个确定的实参浮点数)的话,不会有任何影响(一点都不会有)。

但是,如果一开始就定义一个变量temp,并且temp一直自加一个浮点数,再把temp作为参数多次传进这个分离整数和小数的函数,那么它的结果误差会越来越大。

比如下面这个例子

float temp = 26.90f;
unsigned int  value_integer;
unsigned char value_decimal;

while(1)
{
	Separate_IntegerAndDecimal(temp,&value_integer,&value_decimal);
	printf("value_integer = %d",value_integer);
	printf("value_decimal = %d",value_decimal);
	temp += 0.10f;
	delay_ms(500);
}

你可能感兴趣的:(C语言操作)