当前位置: 首页 > news >正文

float32转float16、snorm/sunorm8/16 学习及实现

1、基础

彻底搞懂float16与float32的计算方式-CSDN博客

例1:float32 0x3fd00000 = 32'b0 011_1111 _1 101_0000_0000_0000_0000_0000 

sign=0

exp=8'b0111_1111 = 'h7f = 'd127 =>0ffset = 127-127 = 0

mantissa =  'b101_0000_0000_0000_0000_0000(补1,1.1010000....)

(-1)^sign * 2^exp_offset * mantissa = 1.101b = 2^0 + 2^(-1) + 2^(-3) = 1.625 d 

例2:  float32 0x3f200000 = 32'b0 011_1111 _0 010_0000_0000_0000_0000_0000

sign=0

exp=8'b0111_1110 = 'h7e = 'd127 =>0ffset = 126-127 = -1

mantissa =  'b010_0000_0000_0000_0000_0000(补1,1.0100000....)

(-1)^sign * 2^exp_offset * mantissa = 1.010 * 2^(-1) b = 0.101= 2^(-1) + 2^(-3) = 0.625 d 

特殊情况,exp 全1时候的nan、inf,exp=0 时候的denorm / 0 

DXGI FOMAT中的SNORM和 UNORM格式-CSDN博客

根据上面的理解,要实现的

snorm8 能够表示的数据为 int(-1.0 ,1.0)* 127 ;

unorm8 能够表示的数据为 int(0,1.0)*255;

snorm16 能够表示的数据为 int(-1.0 ,1.0)* (2^15-1);

unorm16 能够表示的数据为 int(0,1.0)*(2^16-1);

2、实现(sv)

function bit[31:0] float32_to_newformat(bit [31:0] float32_in, TRANSFORM_TYPE type);bit [31:0] rt_data_out;bit [7: 0] unorm8_out;bit [7: 0] snorm8_out;bit [15:0] float16_out;bit [15:0] unorm16_out;bit [15:0] snrom16_out;bit sign;bit [7: 0] exponent;bit [22:0] mantissa;bit [23:0] norm_mantissa;int exp_offset;bit [47:0] shifted_value;bit [7: 0] unorm8_value;bit [7: 0] snorm8_value;bit [15:0] unorm16_value;bit [15:0] snrom16_value;bit [4: 0] exp16;bit [9: 0] mant16;bit overflow,underflow,is_inf,is_nan;//note1sign     = float32_in[31];exponent = float32_in[30:23];mantissa = float32_in[22:0];norm_mantissa = {1'b1,mantissa};if (type == UNORM8)beginif (exponent >=127)begin                        //note2.1if (exponent == 8'ff && mantissa != 0)      //note2.1.1unorm8_value = 8'h0;else                                        //note2.1.2unorm8_value = 8'hff;end else if (exponent >=118)begin               //note2.2shifted_value = norm_mantissa[23:0] * 255;if (shifted_value[23+127-exponent-1] == 1)  //note2.2.1unorm8_value = (shifted_value>>(23+127-exponent)) + 1;elseunorm8_value = shifted_value>>(23+127-exponent);end else                                        //note2.3unorm8_value = 8'h0;unrom8_out = sign? 8'h0 : unorm8_value;         //note2.4end else if (type == SNORM8)beginif (exponent >=127)begin                        if (exponent == 8'ff && mantissa != 0)     snorm8_value = 8'h0;else                                        snorm8_value = 8'h7f;end else if (exponent >=119)begin               shifted_value = norm_mantissa[23:0] * 127;if (shifted_value[23+127-exponent-1] == 1)  snorm8_value = (shifted_value>>(23+127-exponent)) + 1;elsesnorm8_value = shifted_value>>(23+127-exponent);end else                                        snorm8_value = 8'h0;snrom8_out = sign? (-snorm8_value): snorm8_value;        end else if (type == FLOAT16)beginexp_offset = exponent - 127 + 15;overflow   = (exp_offset >= 31);underflow  = (exp_offset <= 0);is_inf     = (exponent = 8'hff && mantissa == 23'h0);is_nan     = (exponent = 8'hff && mantissa != 23'h0);//note3.1exp16      = (overflow && exponent != 8'hff) ? 5'h1e :(is_inf | is_nan) ? 5'h1f :underflow ? 5'h0  : exp_offset[4:0];//note3.2mant16     = (overflow && exponent != 8'hff) ? 10'h3ff :is_inf  ? 10'h0   :is_nan  ? {1'b1,mantissa[21:13]}:underflow ?(mantissa == 23'h0 ? 10'h0 : norm_mantissa[23:13] >> (1-exp_offset)): mantissa[22:13];float16_out = {sign,exp16,mant16};                                         end else if (type == UNORM16)beginif (exponent >=127)begin                        if (exponent == 8'ff && mantissa != 0)     unorm16_value = 16'h0;else                                        unorm16_value = 16'hffff;end else if (exponent >=111)begin               shifted_value = norm_mantissa[23:0] * 65535;if (shifted_value[23+127-exponent-1] == 1)  unorm16_value = (shifted_value>>(23+127-exponent)) + 1;elseunorm16_value = shifted_value>>(23+127-exponent);end else                                        unorm16_value = 16'h0;unrom16_out = sign? 16'h0: unorm16_value;  end else if (tyep == SNORM16)beginif (exponent >=127)begin                        if (exponent == 8'ff && mantissa != 0)     snorm16_value = 16'h0;else                                        snorm16_value = 16'h7fff;end else if (exponent >=112)begin               shifted_value = norm_mantissa[23:0] * 32767;if (shifted_value[23+127-exponent-1] == 1)  snorm16_value = (shifted_value>>(23+127-exponent)) + 1;elsesnorm16_value = shifted_value>>(23+127-exponent);end else                                        snorm16_value = 16'h0;snrom16_out = sign? (-snorm16_value): snorm8_value;  endendfunction

3、代码说明

note1  float32 的拆分,1bit sign,8bit exp,23 bit尾数,补上舍去的1

note2.1 对于norm/snorm 来讲表示-1.0~1.0或者0~1.0 之间的数值,如果指数大于127表示offset 大于0,浮点数大于1了,可以直接设置为最大值

note2.1.1 但是对于 特殊情况,exp 为全1,且mantissa 不等于0 表示无效值,针对无效值赋值为0

note 2.1.2 对于unorm 不考虑符号,所以最大值为全1,对于snorm ,考虑符号位,最高位为0,其余为1

note2.2  对于unrom8,数值转换需要× 255,约2^8,exp>118 才有机会大于0,如果exp再小一些,等于0

note2.2.1 round

note 2.3  见 note2.2

note 2.4  unorm时,sign为1,表示负数,不在unorm表示范围,赋值为0,snorm时候,取负值

note 3.1  exp16转换时候的特殊情况:

        overflow时且is_inf ,is_nan不成立,表示为能够表示的最大数(1f是特殊值,所以是1e)

        is_inf,is_nan 成立时候exp16 全1,

        underflow时为0,

        其余取计算出来的exp_offset

note 3.2 mant16 转换时候的特殊情况:

        overflow时且is_inf ,is_nan不成立,表示为能够表示的最大数

         is_inf,时候根据定义mant16 应该为0,

        is_nan 时候按道理取mant32 的高10位即可,但是防止高10位都为0的情况(这样会转换成is_inf),所以最高位强制为1(反正无效,哪一位强制都可以)

        underflow时,如果mant32 为0 那就是0,否则要使用特殊公式

        正常情况取mant32的高10位

        其余取计算出来的exp_offset

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 浅析DNS服务器:办公网DNS的架构思路分享
  • 深度学习6--深度神经网络
  • 【政策分享】最全!2023-2024年国家遥感政策汇总
  • 华为OD机试(C卷,200分)- 可以组成网络的服务器
  • Sparksql array相关函数
  • gin-vue-admin框架遇到AxiosError:Network Error怎么解决?
  • redis--分布式锁(1)
  • Python(模块---pandas+matplotlib+pyecharts)
  • Apache OFBiz 曝出严重漏洞,允许预身份验证 RCE
  • 第一篇Linux介绍
  • 如何调整 PDF 文件大小
  • 【OpenCV C++20 学习笔记】拉普拉斯(Laplace)二阶求导-边缘检测
  • 【游戏引擎之路】登神长阶(九)——《3D游戏编程大师技巧》:我想成为游戏之神!
  • 【JavaEE精炼宝库】网络原理基础——UDP详解
  • QT实现一个系统参数管理窗口
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • Java超时控制的实现
  • Joomla 2.x, 3.x useful code cheatsheet
  • JSONP原理
  • Linux后台研发超实用命令总结
  • magento 货币换算
  • Python学习之路13-记分
  • quasar-framework cnodejs社区
  • React+TypeScript入门
  • SQL 难点解决:记录的引用
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • vue 个人积累(使用工具,组件)
  • 高度不固定时垂直居中
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 想写好前端,先练好内功
  • 小程序开发之路(一)
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ‌JavaScript 数据类型转换
  • $(this) 和 this 关键字在 jQuery 中有何不同?
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (js)循环条件满足时终止循环
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (八十八)VFL语言初步 - 实现布局
  • (二)fiber的基本认识
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (回溯) LeetCode 46. 全排列
  • .gitignore文件设置了忽略但不生效
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .NET WPF 抖动动画
  • .net 流——流的类型体系简单介绍
  • .Net 路由处理厉害了
  • .Net6 Api Swagger配置
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .NetCore+vue3上传图片 Multipart body length limit 16384 exceeded.