宏定义与UINT做减法

#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <limits.h> #include <math.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_t)(((int64_t)(a) * (b)) >> FRAC_BITS)) // 除法(使用优化函数) #define fixed_div(a, b) s16q16_div_optimized(a, b) // 优化的定点除法(含舍入和饱和处理) 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; } 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); 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))); return 0; } 为什么这段乘法的输出不对?
07-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值