基于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://xiahunao.cn/news/3030532.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

vue-fontawesome-elementui-icon-picker选择icon框架

第一步&#xff1a;安装vue-fontawesome-elementui-icon-picker依赖 npm install vue-fontawesome-elementui-icon-picker --save-dev 第二步&#xff1a;main.js配置 (放在element ui引入之后) import iconPicker from vue-fontawesome-elementui-icon-picker; Vue.use(ico…

【JavaEE网络】用Form与Ajax构建HTTP请求

目录 通过 form 表单构造 HTTP 请求form 发送 GET 请求form 发送 POST 请求 通过 ajax 构造 HTTP 请求发送 GET 请求发送 POST 请求发送 application/json 数据封装 ajax 方法 通过 form 表单构造 HTTP 请求 form (表单) 是 HTML 中的一个常用标签. 可以用于给服务器发送 GET …

机器学习求数组的迹

机器学习求数组的迹、也叫求矩阵的迹。 矩阵的迹&#xff0c;也称为迹数&#xff0c;是矩阵主对角线上所有元素的和。矩阵的迹具有以下重要性质&#xff1a;- 不变性&#xff1a;矩阵的迹在转置、加法、乘法等运算下保持不变。- 特征值关系&#xff1a;一个方阵的迹等于其所有特…

LeetCode题练习与总结:反转链表Ⅱ--92

一、题目描述 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], left 2, right 4 输出&#…

Redis不同数据类型value存储

一、Strings redis中String的底层没有用c的char来实现&#xff0c;而是使用SDS数据结构( char buf[])。 缺点:浪费空间 优势: 1.c字符串不记录自身的长度&#xff0c;所以获取一个字符串长度的复杂度是O(N),但是SDS记录分配的长度alloc,已使用长度len&#xff0c;获取长度的…

MOS管栅极驱动自举电路设计

自举式驱动电路工作原理 自举式电路在高电压栅极驱动电路中是很有用的,其工作原理如下: 当 VS 降低到 IC 电源电压 VDD以下(至少要比VDD低一个二极管压降) 或下拉至地时 (低端开关导通,高端开关关断),电源 VDD 通过自举电阻RBOOT,和自举二极管DBOOT,对自举电容CBOOT…

产业互联网助力预制菜出海 云创科技数据资产入表获批融资500万 新能源装备新质供应链创新协同平台启动 | 产业互联网观察第173期

产业互联网助力预制菜迈向国际市场 在第135届广交会上&#xff0c;一场聚焦“产业互联网赋能预制菜出海”的高端对话会隆重举办。本次活动由中国食品土畜进出口商会主办&#xff0c;云食界网络科技有限公司承办&#xff0c;吸引了众多政府领导、行业专家和企业代表参与。各界共…

跨境电商行业蓬勃发展,武汉星起航引领卖家孵化新潮流

近年来&#xff0c;我国跨境电商行业在政府的大力扶持下呈现出强劲的发展势头。随着国内制造业结构的加速调整与居民消费需求升级态势的持续凸显&#xff0c;跨境出口规模占比稳步提升&#xff0c;跨境进口规模同样不断扩大&#xff0c;行业市场规模持续增长。在这一背景下&…

计算概论学习笔记(1)

感谢北大李戈老师讲解的计算概论。 【道阻且长&#xff0c;行则将至】 很多年没有intensive coding&#xff0c;现在这个系列是coding retake&#xff0c;一点点回忆之前的知识&#xff0c;希望能重回到一线。主要内容包括C,C,Pytorch学术前沿项目学习和实践&#xff0c;预计…

ESLint: Unexpected ‘debugger‘ statement.(no-debugger)(debugger报红)

ESLint: Unexpected debugger statement.(no-debugger) 解决办法&#xff1a; 找到.eslintrc.js文件中rules的no-debugger更改为0即可

【35分钟掌握金融风控策略18】贷前风控策略详解-3

目录 ​编辑 贷前风控数据源 第三方数据 贷前风控数据源 第三方数据 在金融风控过程中&#xff0c;金融机构通常会引入一些第三方的风控数据&#xff08;或第三方金融技术&#xff09;来辅助识别贷款个人或贷款企业的风险状况&#xff0c;帮助金融机构进行风控决策&#x…

Linux vscode push报错fatal: Authentication failed

注意啊&#xff0c;Git基于密码的身份验证已经被删除了&#xff0c;所以这个报错发生时无论密码正确与否&#xff0c;以及参考比较旧的改bug教程&#xff0c;都没法提交。进入提示的网址&#xff0c;生成个人访问令牌就好了

【qt】联合容器和集合容器

联合容器和集合容器 一.QMap1.应用场景2.添加数据3.删除数据4.修改数据5.查找数据6.数据个数7.是否包含8.返回所有的键名 二.QHash1.应用场景&#xff1a; 三.QMultiMap四.QMultiHash五.QSet1.应用场景2.交集3.并集4.差集 总结&#xff1a; 一.QMap 1.应用场景 QMap的底层实现…

字符以及字符串函数

字符以及字符串函数 求字符串长度strlen 长度不受限制的字符串函数strcpystrcatstrcmp 长度受限制的字符串函数strncpystrncatstrncmp 字符串查找strstrstrtok 错误信息报告strerror 字符分类函数字符转换函数tolowertoupper 内存操作函数memcpymemmovememcmpmemset 这篇文章注…

Ubuntu(Linux)Windows 网络连接问题

需求&#xff1a;实现Ubuntu和Windows系统间以太网连接。 Windows端口以太网配置选择IPv4&#xff0c;配置自己的IP&#xff0c;子网掩码不需要填&#xff0c;系统自动补全&#xff0c;默认网关不需要填。 Ubuntu系统为22.04&#xff0c;如果使用网络设置完成IPv4地址设置&…

日本住宅IP:安全、高效的新选择

在信息化社会&#xff0c;网络已成为人们工作、生活不可或缺的一部分。而IP地址&#xff0c;作为网络中的身份证&#xff0c;其重要性不言而喻。近年来&#xff0c;随着跨境业务、网络安全需求以及个人隐私保护意识的增强&#xff0c;日本住宅IP代理逐渐进入人们的视野&#xf…

分布式事务技术方案

什么是分布式事务 一次课程发布操作需要向数据库、redis、elasticsearch、MinIO写四份数据&#xff0c;这里存在分布式事务问题。 什么是分布式事务&#xff1f; 首先理解什么是本地事务&#xff1f; 平常我们在程序中通过spring去控制事务是利用数据库本身的事务特性来实现…

如何远程控制另一部手机:远程控制使用方法

在现今高科技的社会中&#xff0c;远程控制手机的需求在某些情境下变得越来越重要。不论是为了协助远在他乡的家人解决问题&#xff0c;还是为了确保孩子的在线安全&#xff0c;了解如何实现这一功能都是有益的。本文将为您简要介绍几种远程控制手机的方法及其使用要点。 KKVi…

模电·场效应管放大电路的三种接法

场效应管放大电路的三种接法 场效应管的源极、栅极和漏极与晶体管的发射极、基极和集电极相对应因此在组成放大电路时也有三种接法&#xff0c;即共源放大电路、共漏放大电路和共栅放大电路。以N沟道结型场效应管为例&#xff0c;三种接法的交流通路如图1.所示。 图1. 场效应管…

每日一题8:Pandas-改变数据类型

一、每日一题 编写一个解决方案来纠正以下错误&#xff1a; grade 列被存储为浮点数&#xff0c;将它转换为整数。 返回结果格式如下示例所示。 解答&#xff1a; import pandas as pddef changeDatatype(students: pd.DataFrame) -> pd.DataFrame:students[grade] studen…