C语言中将浮点数四舍五入取整的宏定义(支持正数和负数的圆整)

在实际工程项目中经常会需要将浮点型的计算结果四舍五入为整型,因此定义如下宏定义对浮点型进行圆整。若所需圆整的浮点型结果正负号无法确定,则需要将结果圆整为带符号的整型结果如int8_t、int16_t、int32_t等。对于结果>0的浮点数和<0的浮点数圆整时有不同的操作,这一点在实现四舍五入时需特别注意。

typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned int uint32_t;
typedef signed int int32_t;

#define ROUND_TO_UINT8(x)  	(((uint8_t)((x) + 0.5) > (uint8_t)(x)) \
? ((uint8_t)(x) + 1U) : ((uint8_t)(x))) 

#define ROUND_TO_INT8(x) 		(((int8_t)(x) > 0) \
? (((int8_t)((x) + 0.5) > (int8_t)(x)) ? ((int8_t)(x) + 1) : ((int8_t)(x))) \
: (((int8_t)((x) - 0.5) < (int8_t)(x)) ? ((int8_t)(x) - 1) : ((int8_t)(x))))

#define ROUND_TO_UINT16(x)  (((uint16_t)((x) + 0.5) > (uint16_t)(x)) \
? ((uint16_t)(x) + 1U) : ((uint16_t)(x))) 

#define ROUND_TO_INT16(x) 	(((int16_t)(x) > 0) \
? (((int16_t)((x) + 0.5) > (int16_t)(x)) ? ((int16_t)(x) + 1) : ((int16_t)(x))) \
: (((int16_t)((x) - 0.5) < (int16_t)(x)) ? ((int16_t)(x) - 1) : ((int16_t)(x))))

#define ROUND_TO_UINT32(x)  (((uint32_t)((x) + 0.5) > (uint32_t)(x)) \
? ((uint32_t)(x) + 1U) : ((uint32_t)(x))) 

#define ROUND_TO_INT32(x) 	(((int32_t)(x) > 0) \
? (((int32_t)((x) + 0.5) > (int32_t)(x)) ? ((int32_t)(x) + 1) : ((int32_t)(x))) \
: (((int32_t)((x) - 0.5) < (int32_t)(x)) ? ((int32_t)(x) - 1) : ((int32_t)(x))))

使用DEVC 使用如下代码进行验证,可正确实现正数和负数的四舍五入

#include <stdio.h>
#include <stdlib.h>

typedef unsigned short uint16_t;
typedef signed short int16_t;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#define ROUND_TO_UINT16(x)  (((uint16_t)((x) + 0.5) > (uint16_t)(x)) \
? ((uint16_t)(x) + 1U) : ((uint16_t)(x))) 
#define ROUND_TO_INT16(x) 	(((int16_t)(x) > 0) \
? (((int16_t)((x) + 0.5) > (int16_t)(x)) ? ((int16_t)(x) + 1) : ((int16_t)(x))) \
: (((int16_t)((x) - 0.5) < (int16_t)(x)) ? ((int16_t)(x) - 1) : ((int16_t)(x))))

int16_t volt_to_adc_convert(int16_t volt)
{
	float f_value = (float)(volt) / (6.144f * 1000) * 32768;
	int16_t i16_value = ROUND_TO_INT16(f_value);

	printf("[volt]: %5dmV	[raw_adc]: %10.4f  [ADC]:%5d\n", volt, f_value, i16_value);
	
	return i16_value;
} 

int main(int argc, char *argv[])
{
	int16_t i16_i = 0;
	
	for (i16_i = 0; i16_i < 100; i16_i++)
	{
	 	volt_to_adc_convert(5000 - (100 * i16_i));
	} 
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43885532/article/details/109599439