“int_fast16_t”: 重定义;不同的基类型

本文介绍在VS2013环境下,使用RabbitMQ库进行开发时遇到的编译错误,特别是关于int_fast16_t和uint_fast16_t的重定义问题,并提供了解决方案,即通过在头文件中添加特定宏定义来避免与VS自带的stdint.h冲突。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用 rabbitmq 的 库进行开发时遇到问题及,开发环境是vs2013。在编译阶段总是提示以下错误: 

error C2371: “int_fast16_t”: 重定义;不同的基类型

error C2371: “uint_fast16_t”: 重定义;不同的基类型

 

解决方法就是在出问题的头文件中加以下代码可以解决问题:

#if _MSC_VER >= 1600
    #define _MSC_STDINT_H_
#endif

 

原因是stdint.h中定义的int_fast16_t和rabbitmq定义的有重复,vs2013编译器会能够自行寻找stdint.h,所以要在使用的是要要禁止stdint.h,就需要定义_MSC_STDINT_H_宏了。大概就是这么个意思。

#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <limits.h> #include <stdbool.h> // 添加布尔类型支持 // 定义定点数类型(Q16.16格式) typedef int32_t fixed_t; #define FRAC_BITS 16 #define SCALE_FACTOR (1 << FRAC_BITS) // 65536 #define INV_SCALE_FACTOR (1.0f / (float)SCALE_FACTOR) // 预计算倒数 /*=============== 转换宏 ===============*/ // 浮点转定点 #define float_to_fixed(fdata) ((fixed_t)((fdata) * SCALE_FACTOR)) // uint16转定点 #define uint16_to_fixed(udata) ((fixed_t)((uint32_t)(udata) << FRAC_BITS)) // 定点转浮点(优化版) #define fixed_to_float(fixed_data) ((float)(fixed_data) * INV_SCALE_FACTOR) // 定点转uint16(仅适用于非负数) #define fixed_to_uint(fixed_data) ((uint16_t)((fixed_data) >> FRAC_BITS)) /*=============== 运算宏 ===============*/ // 加法(无变化) #define fixed_add(a, b) ((a) + (b)) // 减法(无变化) #define fixed_sub(a, b) ((a) - (b)) // 删除原有的乘法宏,替换为带饱和和舍入的函数 #define fixed_mul(a, b) fixed_mul_saturate(a, b) // 除法(使用优化函数) #define fixed_div(a, b) s16q16_div_optimized(a, b) /*=============== 带饱和和舍入的乘法函数 ===============*/ fixed_t fixed_mul_saturate(fixed_t a, fixed_t b) { // 1. 使用64位中间结果防止计算溢出 int64_t product = (int64_t)a * (int64_t)b; // 2. 添加舍入偏移(0.5 LSB) const int64_t ROUND = 1 << (FRAC_BITS - 1); // 0.5 * SCALE_FACTOR int64_t rounded = product + ((product >= 0) ? ROUND : -ROUND); // 3. 重新缩放并应用饱和 int64_t result = rounded >> FRAC_BITS; // 4. 饱和处理 if (result > INT32_MAX) return INT32_MAX; if (result < INT32_MIN) return INT32_MIN; return (fixed_t)result; } // 优化的定点除法(含舍入和饱和处理) fixed_t s16q16_div_optimized(fixed_t a, fixed_t b) { if (b == 0) return (a >= 0) ? INT32_MAX : INT32_MIN; // 除零保护 int sign = (a ^ b) < 0 ? -1 : 1; uint64_t abs_a = (uint64_t)llabs(a); uint64_t abs_b = (uint64_t)llabs(b); // 添加舍入偏移(0.5 * b) uint64_t dividend = (abs_a << FRAC_BITS) + (abs_b >> 1); uint64_t result = dividend / abs_b; // 应用符号和饱和处理 int64_t signed_result = sign * (int64_t)result; if (signed_result > INT32_MAX) return INT32_MAX; if (signed_result < INT32_MIN) return INT32_MIN; return (fixed_t)signed_result; } /*=============== 高级转换函数 ===============*/ // 仅转换小数部分(高效) float fixed_to_frac_only(fixed_t x) { uint16_t frac = (uint16_t)(x & 0xFFFF); int32_t val = (x < 0) ? (int32_t)frac - 0x10000 : (int32_t)frac; return (float)val * INV_SCALE_FACTOR; } // 通用转换(整数+小数分离处理) float fixed_to_float_general(fixed_t x) { int32_t int_part = x >> FRAC_BITS; uint16_t frac = (uint16_t)(x & 0xFFFF); float f_frac = (x < 0) ? (int32_t)frac - 0x10000 : (int32_t)frac; f_frac *= INV_SCALE_FACTOR; return (float)int_part + f_frac; } /*=============== 溢出检测函数 ===============*/ // 检测乘法是否可能溢出 bool fixed_mul_will_overflow(fixed_t a, fixed_t b) { // 计算整数部分的最大值 const int32_t MAX_INT_PART = INT32_MAX >> FRAC_BITS; // 提取整数部分(考虑符号) int32_t a_int = a >> FRAC_BITS; int32_t b_int = b >> FRAC_BITS; // 检查整数部分是否可能溢出 if (a_int > MAX_INT_PART || b_int > MAX_INT_PART) { return true; } // 更精确的范围检查 int64_t product = (int64_t)a * (int64_t)b; int64_t max_val = (int64_t)INT32_MAX << FRAC_BITS; int64_t min_val = (int64_t)INT32_MIN << FRAC_BITS; return (product > max_val) || (product < min_val); } int main() { // 转换测试 float f = 50.01f; uint16_t u = 8635; fixed_t fixed_f = float_to_fixed(f); fixed_t fixed_u = uint16_to_fixed(u); printf("浮点数 %.5f → 定点数: 0x%08X\n", f, fixed_f); printf("无符号数 %u → 定点数: 0x%08X\n", u, fixed_u); printf("定点数 0x%08X → 浮点数(宏): %.5f\n", fixed_f, fixed_to_float(fixed_f)); printf("定点数 0x%08X → 浮点数(通用): %.5f\n", fixed_f, fixed_to_float_general(fixed_f)); printf("定点数 0x%08X → 无符号数: %u\n", fixed_u, fixed_to_uint(fixed_u)); // 运算测试 - 原始问题数值 fixed_t a = float_to_fixed(50.01f); fixed_t b = float_to_fixed(8635.2f); // 检查是否会溢出 if (fixed_mul_will_overflow(a, b)) { printf("\n警告: 乘法运算将溢出! (%.2f * %.2f = %.2f > %.2f)\n", fixed_to_float(a), fixed_to_float(b), fixed_to_float(a) * fixed_to_float(b), fixed_to_float(INT32_MAX)); } printf("\n运算演示 (50.01 和 8635.2):\n"); printf("加法: %.3f\n", fixed_to_float(fixed_add(a, b))); printf("减法: %.3f\n", fixed_to_float(fixed_sub(a, b))); printf("乘法: %.3f (饱和值)\n", fixed_to_float(fixed_mul(a, b))); printf("除法: %.8f\n", fixed_to_float(fixed_div(a, b))); // 添加安全范围内的测试 fixed_t safe_a = float_to_fixed(10.5f); fixed_t safe_b = float_to_fixed(2.5f); printf("\n安全范围测试 (10.5 * 2.5):\n"); printf("预期结果: 26.25\n"); printf("实际结果: %.3f\n", fixed_to_float(fixed_mul(safe_a, safe_b))); // 测试舍入效果 fixed_t round_a = float_to_fixed(1.1f); fixed_t round_b = float_to_fixed(1.1f); float exact_result = fixed_to_float(round_a) * fixed_to_float(round_b); printf("\n舍入测试 (1.1 * 1.1):\n"); printf("精确值: %.8f\n", exact_result); printf("优化后: %.8f\n", fixed_to_float(fixed_mul(round_a, round_b))); return 0; } 分析上述代码,给出KEIL的M0内核上的代码深度优化,在保持原有精度和结构的前提下,不要链接到C库,将变量类型拿出来重定义,将绝对值之类的需要连接到C库的函数重定义
最新发布
07-27
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值