float 转定点计算加法和乘法

定点数、浮点数和一些高级语言的实现  定点数、浮点数和一些高级语言的实现     什么是定点数、浮点数?    首先我们要认清一个概念,定点数不一定是整数,浮点数不一定是小数。    如其名,浮点数和定点数的区别就在于浮点和定点上,点就是指小数点。浮点数就是小数点是浮动的,定点数就是小数点是固定不动的。    具体,什么是浮点数?    浮点数是在计算机中用以近似表示任意某个实数。具体的说,这个实数由 阅读详情
float 浮点数转成定点数计算其加法和乘法

需要注意的是,以下的程序是建立在下述条件为真的情况下的:

(sizeof(float) == 4 && sizeof(long long) == 8 && sizeof(int) == 4) == ture

也就是说,一定要保证float和int是占4个字节(32bits),long long是占8个字节(64bits)的。

1, 浮点数转定点乘法
void FixedPointMul(float&a, float& b, float& res)
{
   int ia = *(int*)(&a);
    int ib = *(int*)(&b);
    //正负0的情况下,直接返回
    if (ia == 0x80000000 || ia == 0x0 || ib == 0x80000000 || ib == 0x0)
    {
        res = 0.0f;
        return;
    }
    //实际尾数还要加上最前面的1,这里用Long long的原因是两个24位数的乘法,最多是48位,已超出int
    long long ma = (ia & 0x7fffff) | 0x800000;
    long long mb = (ib & 0x7fffff) | 0x800000;
    //码位
    int ea = ((ia >> 23) & 0xff) - 0x7f;
    int eb = ((ib >> 23) & 0xff) - 0x7f;
    //mul
    long long mc = ma * mb;//相当于a<< (23-ea) a<<(23-eb)
    //计算阶码
    //先计算最高有效位
    int i = 0;
    long long tmp = mc;
    while (tmp != 0)
    {
        tmp >>= 1;
        i++;//得到MSB的位置
    }

    int ec = i - 1 - (23 - ea + 23 - eb) + 0x7f;
    //再右移mc MSB 到第24位
    //把MSB移位到第24位
    //把MSB移位到第24位
    if (i < 24)
        mc = (mc << (24 - i)) & 0xffffff;
    else
        mc = (mc >> (i - 24)) & 0xffffff;
    //
    //标记两个数的正负
    int sa = 0;
    if ((ia & 0x80000000) ^ (ib & 0x80000000))//xor
        sa = 1;//negative
    //float
    //拼接成float
    int rc = 0x00000000;
    rc = rc | (mc & 0x7fffff);
    rc = rc | ((ec << 23) & 0x7fffffff);
    //判断正负
    if (sa == 1)
        rc = rc | 0x80000000;
    res = *(float*)(&rc);
    return;
}
2, 浮点转定点加法(减法可以认为是加上一个负数)
#ifndef MAX
#define MAX(X,Y) ((X)>(Y) ? (X) : (Y))
#endif
void FixedPointAdd(float& a, float& b, float& res)
{
   int ia = *(int*)(&a);
    int ib = *(int*)(&b);
    //考虑正负0的情况
    if (ia == 0)
    {
        res = b;
        if(ib == 0x80000000)
            res = 0.0f;

        return;
    }
    if (ib == 0)
    {
        res = a;
        if (ia == 0x80000000)
            res = 0.0f;
        return;
    }
    //if ((ia & 0x7f800000 == 0x7f800000) | (ib & 0x7f800000 == 0x7f800000));
    //实际尾数还要加上最前面的1
    long long  ma = (ia & 0x7fffff) | 0x800000;
    long long  mb = (ib & 0x7fffff) | 0x800000;
    //码位
    int ea = ((ia >> 23) & 0xff) - 0x7f;
    int eb = ((ib >> 23) & 0xff) - 0x7f;
    //正负
    int sa = ia & 0x80000000;
    int sb = ib & 0x80000000;
    //移动到48位并加上符号运算
    if (ea > eb)
    {//让较大的数的MSB移动到第48位,较小的数对应的移动
        //这样的话,小数点对齐在哪里?
        ma <<= 24;
        //mb如何移动?//mb少移动:ea与eb的绝对值的差
        mb <<= (24 - std::abs(ea - eb));
    }
    else
    {
        mb <<= 24;
        ma <<= (24 - std::abs(ea - eb));
    }
    //考虑符号
    ma = (sa == 0 ? ma : -ma);
    mb = (sb == 0 ? mb : -mb);
    long long mc = ma + mb;
    int i = 0;
    long long tmp = 0;
    //结果符号
    tmp = 0x8000000000000000;
    int sc = ((mc & tmp) == 0 ? 0 : 1);
    if (sc == 1)//说明结果是负数
    {
        mc = -mc;
    }
    //计算阶码
    //先计算最高有效位
    tmp = mc;
    while (tmp != 0)
    {
        tmp >>= 1;
        i++;//得到MSB的位置
    }
    //code
    int ec = 0x7f;
    if (ea > eb)
        ec += ea + (i - 48);
    else
        ec += eb + (i - 48);
    //把MSB移位到第24位
    if (i < 24)
        mc = (mc << (24 - i)) & 0xffffff;
    else
        mc = (mc >> (i - 24)) & 0xffffff;
    //
    //float
    //拼接成float
    int rc = 0x00000000;
    rc = rc | (mc & 0x7fffff);
    rc = rc | ((ec << 23) & 0x7fffffff);
    //判断正负
    if (sc == 1)
        rc = rc | 0x80000000;
    res = *(float*)(&rc);
    return;
}

最后需要注意的是,float占4个字节的情况下,在二进制情况下,共有24bit数字是精确数字,转换到十进制数, 只有6位有效数字是绝对精确的,所以在两个float数字比较其误差时,应注意,第7位及以后的数字是无意义的。
比如说:12345.67888和12345.6999其实对于float的内存来说是一样的,但是它们之间的绝对误差是:0.02111,达到了2%。
再比如:123456.000和123456.9999,在float的内存上是一样的,但是,其绝对差为0.9999。
所以用绝对差来表示两个float数是否相近,是不合理的。

嵌入式开发实战:浮点转定点运算优化与Q格式应用详解 在嵌入式系统与数字信号处理领域,定点数运算是一项基础且关键的技术。其核心原理在于使用整数来模拟小数运算,通过预设的缩放因子(如2的幂次)将浮点数映射到整数域进行处理。这种方法的根本价值在于,它能够以确定性的执行时间、极低的CPU开销和内存占用,替代对硬件浮点单元(FPU)的依赖,从而在资源受限的微控制器(MCU)上实现高性能计算。从技术实现角度看,Q格式(如Q15、Q31)是定义虚拟小数点位和数值精度的通用约定,它规范了定点数的表示与运算规则。这使得定点数技术广泛应用于对实时性、能效和成本有严苛要求的场景, 阅读详情

相关推荐

智能环境感知:STM32多传感器数据融合与报警策略设计

本文详细介绍了基于STM32的多传感器数据融合系统设计,整合DHT11温湿度传感器、MQ-2烟雾检测和光照强度检测模块,通过智能算法实现环境感知与动态报警。系统采用数据滤波、多传感器校验和自适应阈值策略,显著提升监测精度与可靠性,并通过OLED显示屏提供清晰的多级报警界面。

plant的博客 200

矩阵系列:浮点转定点

浮点转定点是个比较基础的知识点吧,所以作为开篇,简单的举几个小例子,通过例子,相信大家都能掌握它。 简单说明一下,浮点包括 符号位|指数位|小数位。浮点的类型包括 单精度浮点数|双精度浮点数。这里用到的是单精度浮点数。单精度浮点数:1位符号位,8位指数位,23位尾数位。也有说是24位尾数位,这里笔者认为这样划分,更便于说明(我的地盘听我的,嘿嘿)。 浮点转定点的步骤如下:a)将浮点数划分 符号位|指数位|小数位; b)计算指数位与偏差位的值;单精度浮点数的偏差值固定为127. c)计算并得到定点数。 看例子

u012938458的博客 1012

【Lane】 Ultra-Fast-Lane-Detection 复现

引言 车道线检测源码复现以及训练自己的数据集 1 环境搭建 conda create -n lane python=3.7 conda activate lane # 激活环境 conda install pytorch torchvision cudatoolkit=10.1 -c pytorch pip install -r requirements.txt 2 下载项目源码 若在服务器上可以用指令下载,否则直接在网址中下载 git clone https://github.com/cfzd/U

qq_44703886的博客 2万+

定点数与浮点数

再正数范围内,数据位和我们所理解的原码相同,但是来到负数的范围的时候,情况就完全不一样了,实际上负数的数据位可以有很方便的计算法则。(注意,使用二补码进行的四则运算的结果也都是二补码),然后二补码得到其真值,若为整数就是读数据位就行了,对于负数的结果,如果不去背表的话,那么其真实值应该是其数据位减1再取反。值得注意的是, 2补码格式还有一个优良的累加溢出性质: 当多个2补码数据相加时, 如果加法的中间结果溢出, 但是如果理论上的最终结果是不溢出的, 则2补码数的加法结果也不会溢出。

TValentine的博客 1584

手把手教你用Boot-Repair快速修复Ubuntu启动分区缺失(附详细命令行步骤)

本文详细介绍了如何使用Boot-Repair工具快速修复Ubuntu启动分区缺失问题,包括诊断、应急准备、自动修复和手动命令操作。通过grub rescue模式下的关键命令和Boot-Repair的图形界面操作,帮助用户高效解决启动分区故障,确保系统恢复正常运行。

weixin_29229989的博客 562

从像素到光影:解析《黑神话:悟空》中Nanite与Lumen的协同渲染革命

本文深度解析了《黑神话:悟空》如何利用Unreal Engine 5的Nanite与Lumen技术实现渲染革命。Nanite处理亿级多边形几何细节,无需传统LOD优化;Lumen提供全动态全局光照,实现实时光线反弹。两者协同工作,为游戏带来电影级视觉体验,重塑了实时渲染的技术标准与工作流程。

f6g7h8i9j的博客 425

有符号定点数加法

对齐小数点后,整数部分位宽少的就扩展符号位;小数部分位宽少的就补0。若有符号定点数A的整数部分(含符号)位宽是m,小数位宽是n。若有符号定点数B的整数部分(含符号)位宽是p,小数位宽是q。则A+B的和的位宽是max(m,p)+max(n,q)+1。在相加时,对齐小数点后再相加。

yan20021441的博客 427

彻底解决tplink路由器无法访问部分https网站

彻底解决tplink无法访问部分https网站

renkai721的专栏 8762

【亲测免费】 浮点数转换器(FloatConv)实战指南

浮点数转换器(FloatConv)实战指南 项目介绍 FloatConv 是一个用于转换浮点数表示的开源工具,由 m-ou-se 开发并维护。它允许用户轻松地将浮点数转换成十六进制形式,反之亦然。支持多种浮点数格式,包括bf16、fp16(IEEE 754二进制16位)、fp32以及fp64(IEEE 754二进制64位)。对于不原生提供这些转换功能的目标平台,FloatConv提供了软件实现;...

gitblog_00653的博客 1581

飞牛fnNAS存储模式RAID 5数据恢复

中介绍了fnNAS存储空间的几个模式,细心的网友应该能感受到,我是非常推崇RAID 5的。但我认为,一般人出现1块硬盘损坏后,就能够赶紧采取处理措施了,再高的容灾等级也无法满足这个用户的需求了。》就完成了飞牛NAS存储空间的说明,包括了如何创建、怎么选择空间模式、RAID 5 硬盘故障后的更换、系统更换/重装后数据盘的恢复等等。在VMware中新建虚拟机,安装好fnNAS后,再向虚拟机添加“已有硬盘”(这就是所谓崩溃虚拟机的数据盘),此时新的fnNAS出现提示。在“选择要添加的硬盘”中,选择刚添加硬盘。

dgnankai的专栏 3008

【AutoCAD中实现双击文本编辑功能】

例如:以下是官方博客例子浅析先加入相关的头文件和库文件。在AutoCAD中有一个很重要的功能,就是双击图形尺寸或文本后会出现一个文本编辑框,用户可在该编辑框中修改文字。本文介绍了如何使用AcEdInplaceTextEditor来实现该功能。实现cad的消息监听。创建一个消息监听的类并在cad中注册来实现消息监听。主要是监听键盘输入。提示:以下是本篇文章正文内容,下面案例可供参考提示:这里对文章进行总结:例如:以上就是今天要讲的内容,本文仅仅简单介绍了的函数和方法。

我的博客 1148

日常随记——浮点数与定点数转化程序设计

本文旨在讨论float字型向定点数字型转换的具体方案,并以10位小数为例。欠缺测试,欢迎交流讨论无。

qq_23297513的博客 866

OTFS 消息传递算法信号检测【附matlab代码详解】

OTFS 消息传递算法方面的一些浅浅理解。

Cuby的博客 4009

Xilinx DSP48E2 slice 一个周期能做几次float32浮点数乘法或者加法?如果是fix 32定点数呢?

理解这一点,关键在于了解 DSP48E2 Slice 的内部硬件结构和其设计目的。DSP Slice 主要包含高性能的乘法器、加法器/累加器 (ALU) 以及相关的预加器、寄存器和控制逻辑,专门用于优化数字信号处理和高性能计算中的常见运算,尤其是乘法和加法/累加操作。一个标准的 DSP48E2 Slice在一个时钟周期内完成一个完整的 float32 浮点数乘法或加法。一个 DSP48E2 Slice在一个周期内完成一个完整的 float32 乘法或加法。

kanhao100的博客 1372

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

浮点转定点(以float32转int8)为例

最终结果是将浮点数7.6表示为定点数122(011111010),通过上面步骤实现浮点数到定点数的转换。小数部分: 1010(二进制)表示为 0.625(十进制),占用 4 位。,是一种神经网络优化方法,一来减少内存需求,而来提高读取和处理的效率。转换为二进制(假设带符号): 122的二进制表示为01111010。整数部分: 111(二进制)表示为 7(十进制),占用 3 位。结果为 7.625,可以认为是进行舍入后的近似值,因此验证通过。符号位 : 0(正数)。转换为整数: 122。

weixin_45697971的博客 3693

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

浮点转定点算法-加法运算

#defineMIN(X,Y)(X>=Y?Y:X) /**浮点的加法运算转换为定点的加法运算 *author:zgr2014-04-03 *1.内存中符号位+阶码+尾数的浮点表示法转换为符号位+整数部分+尾数部分的表示法 *2.找到合适的Q值,并取较大的...

chuwangpian7066的博客 402

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C++大数加法、乘法

C语言或c++在数值计算过程中,我们会发现当计算一些小的数时,计算的结果是对的,但是当我们计算一些大数时,往往与结果不一样。为什么会出现这样的原因呢?以下有一些解释。 一、数据类型的限制 C 和 C++ 中有多种数据类型,每种数据类型都有其特定的取值范围。例如,int类型通常占用 4 个字节,其取值范围在不同的系统中可能有所不同,但一般在 -2147483648 到 2147483647 之间。long long 类型也是有范围的。当计算的数值超出这个范围时,就会发生溢出,导致结果错误。 对于

haochenai的博客 2039

java乘法 加法谁先_java 大数的加法和乘法

1、基本类型:int 二进制位数:32包装类:java.lang.Integer最小值:Integer.MIN_VALUE= -2147483648 (-2的31次方)最大值:Integer.MAX_VALUE= 2147483647 (2的31次方-1)2、基本类型:short 二进制位数:16包装类:java.lang.Short最小值:Short.MIN_VALUE=-32768 (-2的...

weixin_30402231的博客 395

java两数相乘的函数_jquery 加法 乘法运算 精确计算函数

int类型相加不会出现问题,但小数点相加就会出现问题//乘法函数var accMul = function(arg1, arg2){var m=0,s1=arg1.toString(),s2=arg2.toString();try{m+=s1.split(".")[1].length}catch(e){}try{m+=s2.split(".")[1].length}catch(e){}return...

weixin_28921621的博客 715

verilog 定点数、浮点数是什么?怎么表示?怎么做运算?

对于计算机如何表示二进制的定点数的理论,网上及书上都有说明,但是如何用verilog代码写出来呢?这就是本文主要学习的内容。 1. 定点数的表示和运算 1)定点数概念 定点数主要是确定小数点的位置,小数点后的二进制位数越多,所表示的数据的精度就越高,例如下图能表示的精度就是2^(-5)=0.03125,误差也就<0.03125。下图所表示的数= 也可以表示为:0xff/2^5=7.96875. 2)定点数的表示 模块之间的...

weixin_41155462的博客 5977

定点数乘法实战:从Q格式到混合精度与溢出处理

在嵌入式系统、数字信号处理等资源受限场景中,浮点运算单元往往不可用或成本过高,定点数表示法成为关键替代方案。其核心原理是用整数运算模拟小数,通过预设缩放因子(常为2的幂次)来隐含小数点的位置。这种技术能在保证确定性的前提下,显著提升计算效率并降低硬件开销。定点数的工程价值在于为音频处理、图像卷积、传感器数据处理等实时系统提供了可靠的数值计算基础。然而,定点乘法涉及位数扩张、溢出风险、精度损失等挑战,尤其在混合精度运算和矩阵乘法等复杂场景中更为突出。本文以Q格式为基础,通过实例深入解析定点数乘法的核心操作、舍

weixin_33957648的博客 348

float、double计算中精度丢失的处理

参考http://blog.youkuaiyun.com/luweicheng24/article/details/77800688import java.math.BigDecimal; public class T { public static void main(String[] args) { String aaString="37.10"; System.err.println(Do

codehxy的专栏 3997

一个基础而奇怪的问题:算法执行加法、乘法、除法性能无区别?

一个基础而奇怪的问题:算法执行加法、乘法、除法性能无区别? 计算机原理分析觉得:加法、乘法和除法的计算性能依次减少,但减少到什么程度? 编写C程序用30次百万数据计算来測试时间差异性,代码例如以下: #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1...

adr5970的博客 324

STM32 F407 带FPU float Q5.10 运算时间对比

最近在鼓捣FOC 就是那个无刷驱动 用STM32F407+DRV8305的方案 一开始自己写FOC的时候全用的float来计算,后来遇到一点(亿点点)问题,便在网上借鉴别(^C + ^V)人的代码,发现有人使用了定点数来运算,便好奇两种方式速度能差多少,就做了下对比(本来我以为定点可以秒杀浮点 哪怕有FPU) 平台:STM32F407 开FPU freertos系统滴答频率是1000HZ,所以1tick就是1ms keil关闭代码优化(开了也一样) 首先自己定义了Q5.10 的数据结构(我试了试Q10.21

qq_23484919的博客 4414

java无限大加法和乘法的实现

Java中存储数字的类型有 short,int,long,double,float。他们的存储数据的大小是有限制的。以下来回顾下各个数据类型的存储大小的差别:1、基本类型:short 二进制位数:16 包装类:java.lang.Short 最小值:Short.MIN_VALUE=-32768 (-2的15此方)最大值:Short.MAX_VALUE=32767 (2的15次方-1)2、基本类型:...

weixin_42314220的博客 1565
上一篇: IEEE754 C++ float的内存布局.md
下一篇: google test 学习笔记1-google test primer.md
beichen
博客等级 码龄16年 4粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值