小编典典

您可以使用Float.intBitsToFloat()和Float.floatToIntBits()在原始浮点值之间进行转换。如果您可以采用截断的精度(而不是舍入),那么只需少量的移位就可以实现转换。

我现在付出了更多的努力,结果却没有一开始就那么简单。现在,该版本已经在我能想到的各个方面进行了测试和验证,我非常有信心它可以为所有可能的输入值产生准确的结果。它支持任一方向上的精确舍入和次正规转换。

// ignores the higher 16 bits

public static float toFloat( int hbits )

{

int mant = hbits & 0x03ff; // 10 bits mantissa

int exp = hbits & 0x7c00; // 5 bits exponent

if( exp == 0x7c00 ) // NaN/Inf

exp = 0x3fc00; // -> NaN/Inf

else if( exp != 0 ) // normalized value

{

exp += 0x1c000; // exp - 15 + 127

if( mant == 0 && exp > 0x1c400 ) // smooth transition

return Float.intBitsToFloat( ( hbits & 0x8000 ) << 16

| exp << 13 | 0x3ff );

}

else if( mant != 0 ) // && exp==0 -> subnormal

{

exp = 0x1c400; // make it normal

do {

mant <<= 1; // mantissa * 2

exp -= 0x400; // decrease exp by 1

} while( ( mant & 0x400 ) == 0 ); // while not normal

mant &= 0x3ff; // discard subnormal bit

} // else +/-0 -> +/-0

return Float.intBitsToFloat( // combine all parts

( hbits & 0x8000 ) << 16 // sign << ( 31 - 15 )

| ( exp | mant ) << 13 ); // value << ( 23 - 10 )

}

// returns all higher 16 bits as 0 for all results

public static int fromFloat( float fval )

{

int fbits = Float.floatToIntBits( fval );

int sign = fbits >>> 16 & 0x8000; // sign only

int val = ( fbits & 0x7fffffff ) + 0x1000; // rounded value

if( val >= 0x47800000 ) // might be or become NaN/Inf

{ // avoid Inf due to rounding

if( ( fbits & 0x7fffffff ) >= 0x47800000 )

{ // is or must become NaN/Inf

if( val < 0x7f800000 ) // was value but too large

return sign | 0x7c00; // make it +/-Inf

return sign | 0x7c00 | // remains +/-Inf or NaN

( fbits & 0x007fffff ) >>> 13; // keep NaN (and Inf) bits

}

return sign | 0x7bff; // unrounded not quite Inf

}

if( val >= 0x38800000 ) // remains normalized value

return sign | val - 0x38000000 >>> 13; // exp - 127 + 15

if( val < 0x33000000 ) // too small for subnormal

return sign; // becomes +/-0

val = ( fbits & 0x7fffffff ) >>> 23; // tmp exp for subnormal calc

return sign | ( ( fbits & 0x7fffff | 0x800000 ) // add subnormal bit

+ ( 0x800000 >>> val - 102 ) // round depending on cut off

>>> 126 - val ); // div by 2^(1-(exp-127+15)) and >> 13 | exp=0

}

与 本书

相比,我实现了两个小的扩展,因为16位浮点的通用精度相当低,与较大的浮点类型(通常由于精度高而通常不会注意到)相比,这可能使浮点格式的固有异常在视觉上可以感知。

第一个是toFloat()函数中的这两行:

if( mant == 0 && exp > 0x1c400 ) // smooth transition

return Float.intBitsToFloat( ( hbits & 0x8000 ) << 16 | exp << 13 | 0x3ff );

字体大小的正常范围内的浮点数采用指数,因此采用数值大小的精度。但这并不是一个平稳的采用,它是分步进行的:切换到下一个更高的指数将导致一半的精度。现在,对于尾数的所有值,精度都保持不变,直到下一次跳转到下一个更高的指数为止。上面的扩展代码通过返回此特定的半浮点值在覆盖的32位浮点范围的地理中心的值,使这些过渡更加平滑。每个正常的半浮点值都精确映射到8192个32位浮点值。返回值应该恰好在这些值的中间。但是在半浮点指数的过渡处,较低的4096值的精度是较高的4096值的两倍,因此覆盖的数字空间仅为另一侧的一半。所有这8192个32位浮点值都映射到相同的半浮点值,因此,无论将8192中的哪一个转换为32位,然后将其转换回32位,都将产生相同的半浮点值

选择了中间的 32位值。扩展现在导致在过渡像更平滑的半一步SQRT(2)的一个因素,因为在正确的显示 图象 下面而左 画面

应该以可视化的尖锐步骤由两个因素不用抗混叠。您可以安全地从代码中删除这两行以获得标准行为。

covered number space on either side of the returned value:

6.0E-8 ####### ##########

4.5E-8 | #

3.0E-8 ######### ########

第二个扩展是在fromFloat()函数中:

{ // avoid Inf due to rounding

if( ( fbits & 0x7fffffff ) >= 0x47800000 )

...

return sign | 0x7bff; // unrounded not quite Inf

}

此扩展通过保存一些32位值形式(提升为Infinity)来稍微扩展半浮点格式的数字范围。受影响的值为那些没有四舍五入而小于Infinity的值,仅由于四舍五入而变为Infinity的值。如果您不需要此扩展名,则可以安全地删除上面显示的行。

我试图尽可能地优化fromFloat()函数中正常值的路径,由于使用了预先计算和未移位的常量,因此使其可读性降低了。我没有在’toFloat()’上投入过多的精力,因为无论如何它都不会超出查找表的性能。因此,如果速度真的很重要,则可以toFloat()仅使用该函数填充0x10000个元素的静态查找表,然后使用该表进行实际转换。对于当前的x64服务器VM,这大约快3倍,对于x86客户端VM,这大约快5倍。

我在此将代码放入公共领域。

2020-10-18

java 精度函数_Java中的半精度浮点相关推荐

  1. java final 函数_JAVA中Final的用法

    1.         修饰基础数据成员的final 这是final的主要用途,其含义相当于C/C++的const,即该成员被修饰为常量,意味着不可修改.如java.lang.Math类中的PI和E是f ...

  2. java replaceall函数_JAVA中string.replace和string.replaceAll的区别及用法

    展开全部 JAVA中string.replace()和string.replaceAll()的区别及用法乍一看,字面上理解好像replace只替换第一个出现的字符(受javascript的影响),32 ...

  3. java addcallback函数_java中怎么使用callback函数?

    UYOU 在很多场景,作为开发都会想到,在执行完毕一个任务的时候,能执行一个callback函数是多么好的事情.现在模拟一下这个情景:定义三个类.分别是主函数类.callback函数的接口类.业务处理 ...

  4. java 对比函数_java中字符串比较函数和操作函数,详细解析

    java编程语言中关于字符的内容也是极其丰富的,所以学习这方面的知识也十分重要的.今天就来为大家介绍一些与java字符串有关的内容,也就是java中字符串比较函数和操作函数,并为大家进行详细的解析,一 ...

  5. java 匿名函数_Java中的lambda匿名函数使用

    Java中的lambda匿名函数使用 lambda匿名函数的使用是为了满足某些情况下需要临时定义函数,或者事先定义,需要时才使用.在python里面,lambda表达式的表达方式为:lambda 参数 ...

  6. java构造方法函数_Java中的构造方法(构造函数)与普通方法区别

    ** Java中的构造办法(构造函数)与通俗办法差别 ** 一.明白什么是构造办法,什么是通俗办法? 所谓的构造办法,是一种特别的办法,其感化是用来创建对象时初始化对象,即为对象成员变量赋初始值,老是 ...

  7. java math 函数_Java中Math类常用函数总结

    Java中比较常用的几个数学公式的总结: //取整,返回小于目标函数的最大整数,如下将会返回-2 Math.floor(-1.8): //取整,返回发育目标数的最小整数 Math.ceil() //四 ...

  8. java this()函数_java中this关键字的三种用法

    this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针. this的用法在java中大体可以分为3种: 1.普通的直接引用,this相当于是指向当前对象本身. 2.形参与成员名字重 ...

  9. java after 函数_Java中关于Date的before函数和after函数的使用

    // before:d1.before(d2) 只有d1在d2之前才返回true  否则false 相当于 d1 < d2 // after: d1.after(d2) 只有d1在d2之后才返回 ...

最新文章

  1. 理解Python的迭代器(转)
  2. Http代理程序,基于hash缓存实现
  3. 【问链-区块链基础知识系列】 第十四课 数字货币交易所的前世、今生和未来(一)
  4. 【推荐系统】一文梳理序列化推荐算法模型进展
  5. android api 相机,具有相机2 API的Android Lollipop上的ZSL功能
  6. 【C/C++】从技术学习和实际运用的角度来看,C/C++和Java到底区别在哪?C语言、C++学习路线?
  7. java统计词频算法_java实现的统计字符算法示例
  8. 中事件源previous_PM2.5传感器在扬尘监测系统中的应用
  9. 正则表达式 6. 存在(或)
  10. 听说你决定当全职自由漏洞猎人了?过来人想跟你聊聊
  11. Mysql控制流语句
  12. log nginx 显示时间_【日常小知识系列01】Nginx日志简述
  13. MATLAB离散控制系统
  14. 【编程实践】复杂网络的基本知识及实现
  15. 今晚8:00 | CEI Lab 软硬件协同优化专题,顶会MICRO最佳论文作者来啦
  16. Android 自定义搜索框(带搜索图标、清除图标、语音图标)
  17. 你不可不知的宇宙简史
  18. java面试题系列10
  19. 基于java的企业合同管理系统设计(含源文件)
  20. npm报错:npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.

热门文章

  1. Web网页实现登录验证码功能
  2. 2019年国庆节的日子2019国庆节
  3. 2019年的国庆有感
  4. 云客Drupal源码分析之通用唯一识别码UUID
  5. python编写的语音识别+机器人对话+文字播报一体
  6. 联想Thinkpad win10x64专业简体中文原版光盘
  7. MATLAB代码:基于主从博弈的智能小区代理商定价策略及电动汽车充电管理 关键词:电动汽车 主从博弈 动态定价 智能小区 充放电优化
  8. 计算机取证要解决的问题类型,计算机取证问题研究
  9. 10分钟精通微信小程序 | 光速入门【三】
  10. openoffice安装