Java使用BigDecimal解决精确计算的问题
最近有人在微信上给我发了一个数学题目,如下图:

我看了之后感觉很是简单,但是却想了半天才解出来。解出来后我想到了用程序再解一遍,然而精确计算的问题却让人头疼不已。
解题思路:
思路其实很简单,暴力求解就可以,但是当你写了一个四重for循环后你会发现解不出来。由此考虑到结果可能是小数,便把增量改成了float类型,每次自增0.1。
当你写完满心欢喜地运行的时候会发现还是出不来结果。再改成double类型也同样是不行。
这是因为java中float类型相加是把十进制转化为二进制后相加然后把二进制结果再转化成十进制。
于是使用java中自带的BigDecimal类进行计算。
当然使用BigDecimal类与值类型的int、float等有所不同。
1、声明一个BigDecimal
BigDecimal b1=new BigDecimal("10");
这样就声明了一个引用b1指向值为10的BigDecimal对象。注意,BigDecimal的构造方法中的值为String类型。
2、BigDecimal的加减
add:
import java.math.BigDecimal;
public class test3 {
public static void main(String[] args) {
BigDecimal b1=new BigDecimal("1.12");
BigDecimal b2=new BigDecimal("2.14");
System.out.println(b1.add(b2));
}
}
运行结果为:3.26
substract:
import java.math.BigDecimal;
public class test4 {
public static void main(String[] args) {
BigDecimal b1=new BigDecimal("1.12");
BigDecimal b2=new BigDecimal("2.14");
System.out.println(b1.subtract(b2));
}
}
运行结果为:-1.02
PS:乘和除也有对应的方法,此处不再展示。
3、BigDecimal的for循环
import java.math.BigDecimal;
public class test3 {
public static void main(String[] args) {
for(BigDecimal b1=new BigDecimal("1.0");
b1.compareTo(new BigDecimal("5"))!=1;
b1=b1.add(new BigDecimal("0.1"))){
System.out.println(b1);
}
}
}
使用BigDecimal做for循环需要使用BigDecimal中的compareTo方法做判断。compareTo方法判断为true会返回1,否则返回0。
4、解题方法
import java.math.BigDecimal;
public class test2 {
public static void main(String[] args) {
for (BigDecimal a = new BigDecimal("0");
a.compareTo(new BigDecimal("10")) != 1;
a = a.add(new BigDecimal("0.1"))) {
for (BigDecimal b = new BigDecimal("0");
b.compareTo(new BigDecimal("10")) != 1;
b = b.add(new BigDecimal("0.1"))) {
for (BigDecimal c = new BigDecimal("0");
c.compareTo(new BigDecimal("10")) != 1;
c = c.add(new BigDecimal("0.1"))) {
for (BigDecimal d = new BigDecimal("0");
d.compareTo(new BigDecimal("10")) != 1;
d = d.add(new BigDecimal("0.1"))) {
if ((a.add(b)).equals(new BigDecimal("9.0"))
&& b.add(d).equals(new BigDecimal("10.0"))
&& a.add(c).equals(new BigDecimal("10.0"))
&& c.subtract(d).equals(new BigDecimal("6.0")) )
System.out.println(a + "| " + b + " | " + c + " | " + d);
}
}
}
}
}
}
恐怖的四重BigDecimal的for循环。
运行结果:1.5| 7.5 | 8.5 | 2.5
Java使用BigDecimal解决精确计算的问题的更多相关文章
- 使用BigDecimal进行精确计算工具类
package com.develop.util; import java.math.BigDecimal; import java.math.RoundingMode; public class M ...
- Java使用BigDecimal解决浮点型运算丢失精度的问题
@Test public void test1(){ System.out.print(0.05+0.01); } @Test public void test2(){ BigDecimal b1 = ...
- Java BigDecimal进行精确计算
前言 float和double类型的主要设计目标是为了科学计算和工程计算.他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的.然而,它们没有提供完全精确的结果,所以 ...
- Java浮点数float,bigdecimal和double精确计算的精度误差问题总结
(转)Java浮点数float,bigdecimal和double精确计算的精度误差问题总结 1.float整数计算误差 案例:会员积分字段采用float类型,导致计算会员积分时,7位整数的数据计算结 ...
- JAVA中精确计算金额BigDecimal
package com.chauvet.utils; import java.math.BigDecimal; import java.text.DecimalFormat; import java. ...
- 解决java计算中double类型结果不一致问题,使用BigDecimal解决
一.需求:从数据表中读出一个double的数据,比如是3.5,没问题,但是如果再用3.5进行计算,比如乘以100,结果就是350了,而是35000000004 因为是浮点运算,所有语言中的浮点数都会有 ...
- java的数字精确计算问题-BigDecimal
java的数字运算,偶尔会出现精度的问题,以下阐述的 java的BigDecimal类的使用. 例如: System.out.println(0.9+0.3); 结果1.2 System.out.pr ...
- Java使用BigDecimal精确计算的简单公式计算器
由于工作需要,写了一个使用BigDecimal运算的精确计算的计算器(然后发现其实比不用BigDecimal的并好不到哪里去) 只能做加减乘除 double类型的数字在千万级别的时候会转成科学计数法, ...
- java精确除法计算,四舍五入 Java问题通用解决代码
主要用java.math.BigDecimal工具类实现,想要了解BigDecimal类可以看java api 正式版: public static Double divide() ...
随机推荐
- 【推荐】CentOS安装Subversion-1.8.17+HTTP协议支持配置
注:以下所有操作均在CentOS 6.5 x86_64位系统下完成. 我们需要搭建一个自己的SVN服务器. 此外,搭建好的SVN服务器除了需要支持svn协议外,最好还需要支持HTTP协议和HTTPS协 ...
- virtio前端驱动详解
2016-11-08 前段时间大致整理了下virtIO后端驱动的工作模式以及原理,今天就从前端驱动的角度描述下目前Linux内核代码中的virtIO驱动是如何配合后端进行工作的. 注:本节代码参考Li ...
- Python并行编程(一):基本概念
1.线程和进程 进程是应用程序的一个执行实例,比如,在桌面上双击浏览器将会运行一个浏览器.线程是一个控制流程,可以在进程内与其他活跃的线程同时执行.控制流程指的是顺序执行一些机器指令.进程可以包含多个 ...
- DRF频率、分页、解析器、渲染器
DRF的频率 频率限制是做什么的 开放平台的API接口调用需要限制其频率,以节约服务器资源和避免恶意的频繁调用. 频率组件原理 DRF中的频率控制基本原理是基于访问次数和时间的,当然我们可以通过自己定 ...
- SpringBoot与Mybatis整合实例详解
介绍 从Spring Boot项目名称中的Boot可以看出来,SpringBoot的作用在于创建和启动新的基于Spring框架的项目,它的目的是帮助开发人员很容易的创建出独立运行的产品和产品级别的基于 ...
- Linux touch命令
touch命令不常用,一般用于更改文件时间戳,或创建一个空文件 命令选项 -a:只更改访问时间 -c:--no-create 不创建任何文件 -d:--date=字符串 使用指定字符串表示时间而非当前 ...
- 014-HQL中级4-Hive中的三种不同的数据导出方式介绍
根据导出的地方不一样,将这些方式分为三种:(1).导出到本地文件系统:(2).导出到HDFS中:(3).导出到Hive的另一个表中.为了避免单纯的文字,我将一步一步地用命令进行说明. 一.导出到本地文 ...
- java 多线程 day16 CountDownLatch 倒计时计数器
import java.util.concurrent.CountDownLatch;import java.util.concurrent.CyclicBarrier;import java.uti ...
- ITL(Interested Transaction List)理解
一.ITL描述: ITL(Interested Transaction List)是Oracle数据块内部的一个组成部分,位于数据块头(block header),itl由xid,uba,flag,l ...
- 如何使用别人的代码 (特指在MFC里面 或者推广为C++里面)
别人写了一堆代码,给了你源代码.在C++里面 应该是 头文件(.h)和源文件(.cpp). 那么我们如何使用他们呢?? 第一步:将其包含进来 如下图 ,不论是头文件还是源文件都如此 第二步:告诉 ...