基于FPGA的数字信号处理(11)--定点数的舍入模式(2)向最临近值取整nearest

前言

在之前的文章介绍了定点数为什么需要舍入和几种常见的舍入模式。今天我们再来看看另外一种舍入模式:向最临近值取整nearest

10进制数的nearest

nearest向最临近值方向取整。它的舍入方式和四舍五入非常类似,都是舍入到最近的整数,比如1.75 nearest到2,-0.25 nearest到0等。二者唯一的区别在于对0.5这类数据的处理上。

  • 0.5的round结果是1,-0.5的round结果是-1
  • 0.5的nearest结果是1,-0.5的nearest结果是0,也就是说对于0.5(1.5/2.5等)这类数据,它们的nearest结果是都是向上取整

以-2到1.75之间的16个数据(步长0.25)为例,它们的nearest结果是这样的:

从上图可以看到:

  • 正数的nearest,分为两个部分:

    • 小数部分小于等于4时就把小数部分(或者约定精度外的部分)丢掉。例如1.25 >> 1,1.0 >> 1 等
    • 小数部分大于等于5时就把小数部分(或者约定精度外的部分)丢掉然后+1。例如1.5 >> 1 >> 1 + 1 >> 2,0.75 >> 0 >> 0+1 >> 1 等
  • 负数的nearest,也分为两个部分:

    • 小数部分小于等于4时就把小数部分(或者约定精度外的部分)丢掉。例如-1.25 >> -1,-1.0 >> -1 等
    • 小数部分大于等于5时就把小数部分(或者约定精度外的部分)丢掉然后-1。例如 -1.5 >> -1 >> -1 - 1 >> -2,-0.75 >> 0 >> 0-1 >> -1 等
  • 0的nearest,就是直接丢掉小数部分

2进制数的nearest

2进制数的nearest和10进制的nearest类似。以Q4.2格式的定点数(字长4位,小数2位的有符号数)为例,对于负数的小数部分的处理:

  • -2(d) = 10_00(b) nearest后的值为 -2,等价于 10,即舍弃小数部分后的值(10)
  • -1.75(d) = 10_01(b) nearest后的值为 -2,等价于 10,即舍弃小数部分后的值(10)
  • -1.5(d) = 10_10(b) nearest后的值为 -1,等价于 11,即舍弃小数部分后的值(10)再加1
  • -1.25(d) = 10_11(b) nearest后的值为 -1,等价于 11,即舍弃小数部分后的值(10)再加1
  • -1(d) = 11_00(b) nearest后的值为 -1,等价于 11,即舍弃小数部分后的值(11)
  • -0.75(d) = 11_01(b) nearest后的值为 -1,等价于 11,即舍弃小数部分后的值(11)
  • -0.5(d) = 11_10(b) nearest后的值为 0,等价于 00,即舍弃小数部分后的值(11)再加1
  • -0.25(d) = 11_11(b) nearest后的值为 0,等价于 00,即舍弃小数部分后的值(11)再加1

对于正数的小数部分的处理:

  • 1.75(d) = 01_11(b) nearest后的值为 2,此时溢出了,需要扩展位宽,处理方式也是舍弃小数部分的值(001)再加1即010
  • 1.5(d) = 01_10(b) nearest后的值为 2,此时溢出了,需要扩展位宽,处理方式也是舍弃小数部分的值(001)再加1即010
  • 1.25(d) = 01_01(b) nearest后的值为 1,等价于 01,即舍弃小数部分后(01)的值
  • 1(d) = 01_00(b) nearest后的值为 1,等价于 01,即舍弃小数部分后(01)的值
  • 0.75(d) = 00_11(b) nearest后的值为 1,等价于 01,即舍弃小数部分后(00)的值再加1
  • 0.5(d) = 00_10(b) nearest后的值为 1,等价于 01,即舍弃小数部分后(00)的值再加1
  • 0.25(d) = 00_01(b) nearest后的值为 0,等价于 00,即舍弃小数部分后(00)的值

对于0的处理:直接舍弃小数部分。

总结一下,就是:

  • 对于正数的nearest处理:首先舍掉小数位,然后加一个进位值:
    • 当小数部分的最高位为0时,说明这个数的小数部分是小于0.5的,所以不需要进位,此时的进位值为0。
    • 当小数部分的最高位为1时,说明这个数的小数部分是大于等于0.5的,所以需要进位,即此时的进位值为1。
  • 对于0的nearest处理:首先舍掉小数位,然后加一个进位值,该进位值恒定为0。
  • 对于负数的nearest处理:首先舍掉小数位,然后加一个进位值:
    • 当小数部分的最高位为0时,说明这个数的小数部分是小于0.5的,而整数部分又是个负数,相当于二者的和的小数部分小于 -0.5。例如10.01是-1.75,它的小数部分.01是0.25,整数部分10是-2,二者相加是-2+0.25 = -1.75,所以它们的处理方式都是先舍弃小数位,然后加0。
    • 当小数部分的最高位为1且其他位不为全0时,说明这个数的小数部分是大于0.5的,而整数部分又是个负数,相当于二者的和的小数部分大于-0.5。例如10.11是-1.25,它的小数部分.11是0.75,整数部分10是-2,二者相加是-2+0.75 = -1.25。所以它们的处理方式都是先舍弃小数位,然后加1。
    • 当小数部分的最高位为1且其他位为全0时,说明这个数的小数部分是等于0.5的,此时向上舍入,例如11_10是 -0.5,nearest后的值为 0(00),即11_10>>11+1>>00。所以它们的处理方式都是先舍弃小数位,然后加1。

上面的内容可以再精简:

  • 当小数部分的最高位为0时,相当于整数部分 + 进位值,进位值等于0,即小数部分的最高位
  • 当小数部分的最高位为1时,相当于整数部分 + 进位值,进位值等于1,即小数部分的最高位

image-20240421161549486

下面以 用nearest的方式来实现Q4.2格式定点数转Q2.0格式定点数为例,Verilog代码如下:

module test(input	[3:0]	data_4Q2,				//有符号数,符号1位,字长4位,小数2位	output	[1:0]	data_2Q0				//有符号数,符号1位,字长2位,小数0位	
);wire	carry;assign	carry = data_4Q2[1];				//小数的最高位就是进位值				
assign	data_2Q0 = data_4Q2[3:2] + carry;	//舍弃低位(即整个小数部分)后再加进位endmodule

因为一共只有16个数,所以我们可以用穷举的方式来测试,TB如下:

`timescale 1ns/1ns
module test_tb();reg	 [3:0]	data_4Q2;			//有符号数,符号1位,整数2位,小数2位	
wire [1:0]	data_2Q0;			//有符号数,符号1位,整数2位,小数0位	integer i;						//循环变量initial begindata_4Q2 = 0;				//输入赋初值	for(i=0;i<16;i=i+1)begin	//遍历所有的输入,共16个	data_4Q2 = i;						#5; $display("data_4Q2:%h		data_2Q0:%h",data_4Q2,data_2Q0);end#20 $stop();				//结束仿真
end//例化被测试模块
test	test_inst(.data_4Q2	(data_4Q2),	.data_2Q0	(data_2Q0)
);endmodule

同时,我们也用matlab来实现同样的功能,观察两者的输出是否一致:

%--------------------------------------------------
% 关闭无关内容
clear;
close all;
clc;%-------------------------------------------------------------------------------
% 生成数据并做Nearest处理
x = -2:0.25:1.75;
F = fimath('RoundingMethod','Nearest');         	% 设定舍入模式为nearest
%F_c = fimath('RoundingMethod','Convergent');      	% 设定舍入模式为nearest
data_4Q2 = fi(x,1,4,2,F);                         	% 生成Q4.2格式的定点数
data_2Q0 = fi(data_4Q2,1,2,0,F);                  	% 从Q4.2格式转换成Q2.0格式

下图是2者分别输出的数据(16进制),可以看到有2个数是对不上的:

image-20240421013707229

你如果记性不错的话,就会发现这两个数正是前面讨论的正数会出现溢出的情况。这2个数分别是0110/0111,即10进制数1.5/1.75,它们的nearest结果应该是2。从上图来看,好像是matlab错了,而RTL对了,但实际情况恰恰相反。现在想想结果是什么格式的?Q2.0!它能表示的最大的数是多少?是10进制的1!所以结果溢出了!

那为什么RTL的结果又 ”对“ 了呢?这纯属是乌龙。因为打印结果是16进制的,并不表示10进制数值,结合结果的2位位宽,可知 ”2“,实际上就是10,它是01的溢出产生的,这个数在Q2.0格式的定点数中并不表示 ”数字2“,而是数字 ”-1“。

matlab是有溢出处理进制的(saturate),它把溢出值把都饱和在了最大值,即01(10进制的1),所以为了防止这种情况的发生,我们也要设计对应的溢出处理机制。因为负数的最小值只取决于整数(小数部分是正的权重),而正数的最大值同时取决于小数和整数,例如Q4.2格式的最小值是-2即10_00,而最大值则是1.75即01_11,所以溢出只会是正向的溢出,那么就只要限定最大值即可。把Verilog代码改一下:

module test(input	[3:0]	data_4Q2,				//有符号数,符号1位,字长4位,小数2位	output	[1:0]	data_2Q0				//有符号数,符号1位,字长2位,小数0位	
);wire			carry;
wire	[2:0]	data_temp;					//扩展1bit,防止溢出assign	carry = data_4Q2[1];	
assign	data_temp = {data_4Q2[3],data_4Q2[3:2]} + {2'b00,carry};		//中间变量,舍弃低位(即整个小数部分)后再加进位    
assign	data_2Q0 = (data_temp[2:1]==2'b01) ? 2'b01 : data_temp[1:0];	//data_2Q0的高2位为01说明产生了正向的进位,即溢出
endmodule

这样结果就是正确的了:

image-20240421014851058

定点数从Q4.2格式转Q2.0格式是一个比较特殊的例子,因为它相当于把小数部分全部舍弃掉了,如果舍入要求不是全部小数位,而是部分小数位,那么处理方式是一样的吗?

是一样的。对于其他情况则相当于把小数点移动到了对应的位置。例如Q5.3格式的定点数转Q3.1格式,则只需要把最后两位小数舍弃并加上进位即可即可,例如:

00.001 是0.125,距离它最近的Q3.1格式的数是0即00.0,即00.001 >> 00.0 + 0 >> 00.0

00.110 是0.75,距离它最近的Q3.1格式的数就是它0.5和1,但是要求向上取整,所以结果是1即01.0,即00.110 >> 00.1+1 >> 01.0

11.111 是-0.125,距离它最近的Q3.1格式的数是0即00.0,即11.111 >> 11.1+ 1 >> 00.0

10.110 是-1.25,距离它最近的Q3.1格式的数是-1和-1.5,但是要求向上取整,所以结果是-1即11.0,即10.110 >> 10.1+1 >> 11.0

其他类似,不赘述了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/9973.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单链表经典oj题(2)

前言 这次将要把剩下的oj题将以图解和自己的理解把它讲解完&#xff0c;希望对大家有所帮助&#xff0c;这次的讲解也是干货 第一题 21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09; ok这次就简单点&#xff0c;大家自己去看题目了 将两个升序链表合并为一个…

带有-i选项的sed命令在Linux上执行成功,但在MacOS上失败了

问题&#xff1a; 我已经成功地使用以下 sed 命令在Linux中搜索/替换文本&#xff1a; sed -i s/old_string/new_string/g /path/to/file然而&#xff0c;当我在Mac OS X上尝试时&#xff0c;我得到&#xff1a; command i expects \ followed by text我以为我的Mac运行的是…

未授权访问:Memcached 未授权访问漏洞

目录 1、漏洞原理 2、环境搭建 3、未授权访问 防御手段 今天继续学习各种未授权访问的知识和相关的实操实验&#xff0c;一共有好多篇&#xff0c;内容主要是参考先知社区的一位大佬的关于未授权访问的好文章&#xff0c;还有其他大佬总结好的文章&#xff1a; 这里附上大…

K8S三 K8S部署微服务应用

一 用k8s部署微服务应用 以我们之前用docker部署过的eureka应用为例&#xff0c;首先添加配置文件eureka-app-deployment.yaml用于创建Deployment apiVersion: apps/v1 kind: Deployment metadata:name: eureka-app-deployment # deployment名字labels:app: eureka-app spec:…

【C++】CentOS环境搭建-升级CMAKE

【C】CentOS环境搭建-升级CMAKE CMAKE报错CMake 3.12 or higher is required. You are running version 2.8.12.2升级步骤1.移除当前的cmake2.安装必要的构建工具和库3.下载最新的cmake源码并解压5.编译和安装6.验证安装 CMAKE报错CMake 3.12 or higher is required. You are r…

MySQL存储引擎详解

存储引擎 MySQL体系结构 连接层&#xff1a;与客户端连接&#xff0c;权限校验、连接池服务层&#xff1a;SQL接口和解析、查询优化、缓存、函数引擎层&#xff1a;索引、存储引擎存储层&#xff1a;系统文件、日志&#xff08;Redo、Undo等&#xff09; 存储引擎介绍 不同的…

免费远程控制软件哪个好用

免费远程控制软件哪个好用 在现今高度信息化的社会&#xff0c;远程控制软件已成为许多用户进行远程办公、技术支持和教育培训的重要工具。市面上有许多免费的远程控制软件&#xff0c;但哪款才是最好用的呢&#xff1f;本文将为您介绍几款热门的免费远程控制软件&#xff0c;…

Matlab: ode45解微分方程——以弹簧振子模型为例

简介&#xff1a; 在科学和工程中&#xff0c;我们经常遇到描述事物变化的微分方程。这些方程可以帮助我们理解从行星运动到药物在体内的扩散等各种现象。但是&#xff0c;很多微分方程非常复杂&#xff0c;手动求解几乎不可能。这时&#xff0c;我们就可以使用像 ode45这样的…

【iOS】frame与bounds区别

文章目录 前言framebounds两者区别size的区别总结 前言 在学习响应者链的过程中用到了frame与bounds的混用&#xff0c;这两个属性经常出现在我们的开发中&#xff0c;特别撰写一篇博客分析区别 首先&#xff0c;我们来看一下iOS特有的坐标系&#xff0c;在iOS坐标系中以左上…

【debug】如何使用pycharm对代码调试

后续会将所有debug中遇到的知识放入&#xff0c;建议关注收藏 本站友情链接&#xff1a; 基本理论专栏&#xff08;当前更新好的debug所有内容都在这里&#xff09; 【debug】报错解决方法&#xff08;CondaHTTPError&#xff1a;HTTP 000 connection failed for url&#xff…

【回溯 状态压缩 深度优先】37. 解数独

本文涉及知识点 回溯 状态压缩 深度优先 LeetCode37. 解数独 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只…

[C++核心编程-06]----C++类和对象之对象模型和this指针

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

Microsoft 365 for Mac v16.84 office365全套办公软件

Microsoft 365 for Mac是一款功能丰富的办公软件套件&#xff0c;为Mac用户提供了丰富的功能和工具&#xff0c;提高了工作效率和协作能力。Microsoft 365 for Mac是一款专为Mac用户设计的订阅式办公软件套件&#xff0c;旨在提高生产力和效率。 Microsoft 365 for Mac v16.84正…

ubantu安装docker以及docker-compose

ubantu安装docker以及docker-compose 安装docker1、从官方存储库中安装Docker2、启动Docker服务3、验证 安装docker compose使用docker部署服务1、需要再opt文件夹下创建以下文件夹&#xff0c;/opt文件夹目录说明2、可将已备份对应文件夹拷至对应文件夹下3、在/opt/compose目录…

霍金《时间简史 A Brief History of Time》书后索引(A--D)

图源&#xff1a;Wikipedia INDEX A Abacus Absolute position Absolute time Absolute zero Acceleration Age of the universe Air resistance Albrecht, Andreas Alpha Centauri Alpher, Ralph Anthropic principle Antigravity Antiparticles Aristotle Arrows of time …

基于Vant UI的微信小程序开发(随时更新的写手)

基于Vant UI的微信小程序开发✨ &#xff08;一&#xff09;悬浮浮动1、效果图&#xff1a;只要无脑引用样式就可以了2、页面代码3、js代码4、样式代码 &#xff08;二&#xff09;底部跳转1、效果图&#xff1a;点击我要发布跳转到发布的页面2、js代码3、页面代码4、app.json代…

我觉得POC应该贴近实际

今天我看到一位老师给我一份测试数据。 这是三个国产数据库。算是分布式的。其中有两个和我比较熟悉&#xff0c;但是这个数据看上去并不好。看上去第一个黄色的数据库数据是这里最好的了。但是即使如此&#xff0c;我相信大部分做数据库的人都知道。MySQL和PostgreSQL平时拿出…

Spark Streaming笔记总结(保姆级)

万字长文警告&#xff01;&#xff01;&#xff01; 目录 一、离线计算与流式计算 1.1 离线计算 1.1.1 离线计算的特点 1.1.2 离线计算的应用场景 1.1.3 离线计算代表技术 1.2 流式计算 1.2.1 流式计算的特点 1.2.2 流式计算的应用场景 1.2.3 流式计算的代表技术 二…

kernel32.dll丢失要如何解决?电脑kernel32.dll文件下载方法

kernel32.dll丢失要怎么解决才好&#xff1f;其实针对这个问题还是有很多种的解决方法的&#xff0c;只要你明白了kernel32.dll的作用&#xff0c;了解kernel32.dll&#xff0c;那么就可以有很多种方法去解决&#xff0c;下面一起来看看吧。 一.了解kernel32.dll文件 kernel32…

6个超TM好用的神仙App推荐!

1. AI文本视频生成工具——Jurilu Jurilu 是一款功能强大的 AI 文本视频生成器&#xff0c;允许用户快速将文本内容转换成极具吸引力的视频。它的使用非常简单&#xff1a;只需要输入文字&#xff0c;选择想要的样式和模板&#xff0c;Jurilu 就会自动将文字转换成生动的视频。…