在实际工程项目中经常会需要将浮点型的计算结果四舍五入为整型,因此定义如下宏定义对浮点型进行圆整。若所需圆整的浮点型结果正负号无法确定,则需要将结果圆整为带符号的整型结果如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;
}