浮点数分离成整数和小数
因为十进制运算的底层是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);
}