Java 高精度浮点数计算工具
说起编程中的高精度数值,我第一反应就是double类型了。的确,double阶码11位,尾数52位,几乎能应对任何苛刻的要求......然而,当我天真地尝试用double来算泰勒展开式的函数值,离散代数的狰狞性瞬间完全暴露眼前。
我不是数学出身,也并不关心那些奇异的函数形式。我只是想推导一个物理系统的冲击响应函数。那个函数没法求得解析解,我只好用皮卡迭代法求泰勒级数式。经过一番挣扎,级数通项终于确定了,但是函数的绘图却成了隐藏难题。
函数的形式:
\]
函数形似一个衰减的正弦振荡,本应该长这样:

但是实际上泰勒级数绘制出来长这样:

甚至这样:

崩溃了,仔细检查原因,发现最后几项级数取值超过\(10^{300}\),换言之double活生生撑爆了。。。
接下来的几天我在网上查找了半天提高浮点数长度(精度)的方法,但是收获甚微。python的numpy好似有float_128,但其实是80位扩展double。c语言倒是找到了诸如mpfr之类的4精度数计算包,但是这也是治标不治本。
由于我用java做科学计算的习惯(奇异癖好),我决定用java写一个任意精度浮点数计算工具(类)。
LFloat类(large float)原理:
由于电脑显然不能存储太长的数字,我决定用long数组存储浮点数的小数部分。并且,考虑到乘法的计算问题,如果两个long类型的整数直接相乘,最多会有接近64位(二进制)的得数由于long溢出而丢弃,从而达不到准确计算的目的。最后,我只能妥协,每一个long储存32位(二进制)小数部分。
这样的好处在于对于加减乘法,0-31位的进位部分会保存在31-63位处,从而方便后续处理。对于除法,我没有采用较为高效的方法,而只是朴素的逐位作差实现。
另一个难点是数字的输入与输出。由于精度变态,double输入显然不太合适(除了极个别数,一般的double数都是做了近似截断的,不会太准确)。为此只能输入String字符串,再自定义parse函数来读取、存储数字。对于显示,则采取读取数字的逆运算,经过一系列的2-10转换最终输出。
输入输出还有一个难点,即指数的转化。输入、输出的数字都由科学计数法表示,动辄“1E+1000”之类的天文数字。为了便于转化,所有数字输入时都先取log,求出阶码,再用exp函数算出小数部分的二进制数。
成果:
- 实现了任意指定精度的浮点数的运算,并且阶码有62位,最大能表示\(10^{10^{18}}\)这等天文数字!
- 浮点数运算近似符合IEEE 754标准,处理舍入方面直接截断,而没有向偶数取整(其实不太需要,感觉精度差了就多加几位精度呗~)。
一些测试,以及计算\(\pi\)的数值到400位:

代码:
见我的github页面,测试代码也在里面,注释较为详细。
结束语:
经过千辛万苦终于写成了较为高效的高精度浮点数计算代码,编写期间排除bug无数,希望这个工具对大家有所帮助。
p.s.如果有人发现了什么bug(一定有的),或者提出什么可以改进的地方,欢迎留言~
Java 高精度浮点数计算工具的更多相关文章
- java第二周的学习知识4(对原码,补码,反码和java中浮点数计算不准确的总结)
原码:一个正数,转换为二进制位就是这个正数的原码.负数的绝对值转换成二进制位然后在高位补1就是这个负数的原码. 但是原码有几个缺点,零分两种 +0 和 -0 .很奇怪是吧!还有,在进行不同符号的加法运 ...
- JAVA简单精确计算工具类
1 public class ArithUtil { 2 3 // 默认除法运算精度 4 private static final int DEF_DIV_SCALE = 10; 5 6 privat ...
- 计算价格, java中浮点数精度丢失的解决方案
计算价格, java中浮点数精度丢失的解决方案
- java精确计算工具类
java精确计算工具类 import java.math.BigDecimal; import java.math.RoundingMode; import java.math.BigDecimal; ...
- 学以致用:手把手教你撸一个工具库并打包发布,顺便解决JS浮点数计算精度问题
本文讲解的是怎么实现一个工具库并打包发布到npm给大家使用.本文实现的工具是一个分数计算器,大家考虑如下情况: \[ \sqrt{(((\frac{1}{3}+3.5)*\frac{2}{9}-\fr ...
- java中浮点数的比较(double, float)(转)
问题的提出:如果我们编译运行下面这个程序会看到什么? public static void main(String args[]){ System.out.println(0.05+0.01); Sy ...
- 最全的Java操作Redis的工具类,使用StringRedisTemplate实现,封装了对Redis五种基本类型的各种操作!
转载自:https://github.com/whvcse/RedisUtil 代码 ProtoStuffSerializerUtil.java import java.io.ByteArrayInp ...
- 常用 Java 静态代码分析工具的分析与比较
常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基 本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBu ...
- [原创]Java静态代码检查工具介绍
[原创]Java静态代码检查工具介绍 一 什么是静态代码检查? 静态代码分析是指无需运行被测代码,仅通过分析或检查源程序的语法.结构.过程.接口等来检查程序的正确性,找出代码隐藏的错误和缺陷,如参数 ...
随机推荐
- 从微信小程序到鸿蒙js开发【15】——JS调用Java
鸿蒙入门指南,小白速来!0基础学习路线分享,高效学习方法,重点答疑解惑--->[课程入口] 目录:1.新建一个Service Ability2.完善代码逻辑3.JS端远程调用4.<从微信小 ...
- 微信小程序(八)-项目实例(原生框架 MINA转云开发)==03-云开发-数据库
云数据库 云数据库开发文档:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/database.html 1.新建云数据库( ...
- ============================================ 新的开始(前后端分离项目学习Vue+DRF)
- 微信小程序:自定义组件
为什么要学习自定义组件? 1.用上我自己的单词abc,我希望在页面中展示椭圆形的图片, 2.打开手机淘宝,假如现在要做一个企业级项目,里面有很多页面,首页存在导航模块,点击天猫,进入第二个页面,而第二 ...
- LinkedHashMap转对象
当需要把map转为实体对象时,需要结合fastjson来实现,方法如下: LinkedHashMap<String,Object> hashMap = new LinkedHashMap& ...
- 基于西门子S7-1500的大型焊接机全套程序,使用博图V14打开(带全部注释)
程序说明:本套程序是在从事自动化行业时候的做的项目的程序,经过在设备上运行测试,其中包含20多个轴的伺服控制以及模拟量,数字量IO的控制,包括扫描枪的读取,属于大型程序,总步数有好几万步. 本程序注释 ...
- Kubernetes: NGINX/PHP-FPM 502错误和优雅结束
我们有一个运行在Kubernetes上的PHP应用,每个POD由两个独立的容器组成 - Nginx和PHP-FPM. 在我们对应用进行缩容时,遇到了502错误,例如,当一个POD在结束中时,POD里面 ...
- 【图像处理】使用OpenCV+Python进行图像处理入门教程(三)色彩空间
这篇随笔介绍使用OpenCV进行图像处理的第三章 色彩空间. 3 色彩空间 之前的介绍,大多是基于BGR色彩空间进行的,但针对不同的实际情况,研究人员提出了许多色彩空间,它们都有各自擅长处理的领域. ...
- CISCN-2018-Quals-note-service2
CISCN-2018-Quals-note-service2 总结 做完这道题,收获如下: 1)汇编语句jmp short s,最后编译出来的机器码为\xEB\x??,问号代表pc寄存器会往前或往后跳 ...
- find文本处理(locate)实例学习记录
find文本处理(locate)实例学习记录 (一)按文件名称查找 按照文件名称查找是 find 最常见的用法,需要注意的是,搜索的文件名必须完全匹配,才能找到对应的文件. 1. 查找当前目录下所有 ...