浮点数转定点数基础讲解

将浮点数转换为定点数是为了在硬件上实现更高效的计算,特别是在嵌入式系统中。定点数使用整数来表示小数,从而减少了处理器的复杂性并提高了执行速度。以下是关于浮点数转定点数的基本概念和示例讲解:

基本概念

浮点数:浮点数可以表示很大的范围,并且有较高的精度。它通常由符号位、指数部分和尾数部分组成,符合 IEEE 754 标准。

定点数:定点数在特定位数上表示数字,通常用于在资源受限的环境中执行高效计算。定点数的表示通常分为整数部分和小数部分,以固定的小数位数(小数点位置)进行划分。

Q格式:常用的定点数格式。用 Qm.n 表示,其中 m 是整数部分的位数,n 是小数部分的位数。比如,Q1.7 格式表示一个符号位,一个整数位,七个小数位。

定标因子(Scaling Factor):用于将浮点数转换为定点数。定标因子通常为 2^n,其中 n 是小数位数。

溢出和舍入:在转换过程中,需要考虑数值溢出的问题(数值超出表示范围)以及如何舍入(四舍五入、向上舍入等)。

转换步骤

确定定标因子:根据定点数格式选择合适的定标因子。例如,对于 Q1.7 格式,定标因子为
在这里插入图片描述

乘以定标因子:将浮点数乘以定标因子,将其转换为定点数表示。

舍入:对结果进行适当的舍入。

截断/溢出处理:如果结果超出定点数表示范围,需要进行截断或溢出处理。

示例

假设需要将浮点数转换为 Q1.7 格式的定点数:

浮点数转定点数
假设有一个浮点数 0.15625 需要转换为 Q1.7 格式。

确定定标因子
在这里插入图片描述

乘以定标因子

0.15625×128=20

舍入:此例中没有小数部分,舍入结果为 20。

截断/溢出处理:20 在 Q1.7 格式范围内,无需处理。

因此,浮点数 0.15625 在 Q1.7 格式中的定点数表示为 20。

定点数转浮点数
将定点数 20 转回浮点数:

除以定标因子
在这里插入图片描述

编码实现示例

def float_to_fixed(float_num, scale_factor):
    # 乘以定标因子并进行舍入
    fixed_num = int(round(float_num * scale_factor))
    return fixed_num

def fixed_to_float(fixed_num, scale_factor):
    # 除以定标因子
    float_num = fixed_num / scale_factor
    return float_num

# 浮点数
float_number = 0.15625

# 定标因子(Q1.7 格式)
scale_factor = 2**7

# 转换为定点数
fixed_number = float_to_fixed(float_number, scale_factor)
print(f"浮点数 {float_number} 转换为定点数: {fixed_number}")

# 转换回浮点数
converted_float_number = fixed_to_float(fixed_number, scale_factor)
print(f"定点数 {fixed_number} 转换回浮点数: {converted_float_number}")

结论
在浮点数与定点数之间转换时,务必注意数值范围和精度要求。选择合适的 Q 格式以及适当的舍入和溢出处理方式,将确保转换的准确性和有效性。

溢出示例

假设我们要将浮点数 1.5 转换为 Q1.7 格式的定点数:

Q1.7 格式的范围:

范围:Q1.7 格式使用一个符号位,一个整数位和七个小数位。
最大值:0.1111111 = 0.99609375(在定点表示中等于 127)
最小值:-1.0 = -1(在定点表示中等于 -128)
浮点数:1.5

乘以定标因子:

1.5×128=192

结果为 192,超出 Q1.7 格式的表示范围。

溢出处理:当定点数超出范围时,需要进行截断或饱和操作。

C++ 示例代码
下面是一个 C++ 程序,演示如何将浮点数转换为定点数并处理溢出:

#include <iostream>
#include <cmath>
#include <limits>

// 定点数最大值和最小值(Q1.7 格式)
const int8_t FIXED_MAX = 127;  // 0.99609375
const int8_t FIXED_MIN = -128; // -1.0

// 浮点数转定点数函数
int8_t floatToFixed(float float_num, int scale_factor) {
    // 转换为定点数
    int fixed_num = std::round(float_num * scale_factor);

    // 溢出处理(饱和算子)
    if (fixed_num > FIXED_MAX) {
        fixed_num = FIXED_MAX;
    } else if (fixed_num < FIXED_MIN) {
        fixed_num = FIXED_MIN;
    }

    return static_cast<int8_t>(fixed_num);
}

// 定点数转浮点数函数
float fixedToFloat(int8_t fixed_num, int scale_factor) {
    return static_cast<float>(fixed_num) / scale_factor;
}

int main() {
    // 浮点数
    float float_number = 1.5;

    // 定标因子(Q1.7 格式)
    int scale_factor = 128;

    // 转换为定点数
    int8_t fixed_number = floatToFixed(float_number, scale_factor);
    std::cout << "浮点数 " << float_number << " 转换为定点数: " << static_cast<int>(fixed_number) << std::endl;

    // 转换回浮点数
    float converted_float_number = fixedToFloat(fixed_number, scale_factor);
    std::cout << "定点数 " << static_cast<int>(fixed_number) << " 转换回浮点数: " << converted_float_number << std::endl;

    return 0;
}

代码解释
定标因子:定义为 128,对应 Q1.7 格式。
溢出处理:使用饱和算子进行溢出处理,如果数值超过最大值或最小值,则设置为最大值或最小值。
floatToFixed 函数:将浮点数乘以定标因子并四舍五入,进行溢出处理后返回定点数。
fixedToFloat 函数:将定点数除以定标因子,转换回浮点数。
结果
运行代码将输出:

浮点数 1.5 转换为定点数: 127
定点数 127 转换回浮点数: 0.992188

总结
在定点数转换中,溢出处理是关键步骤,特别是当数值超出定点数表示范围时。通过适当的溢出处理(如饱和算子),可以确保转换结果在合理范围内,避免计算错误。

  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值