BigDecimal 专题

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;

public class AddSubtractMultiplyDivide {

    public static void main(String[] args) {
        String q1 = "0.06 + 0.01 =";
        String q2 = "1.0 - 0.42=";
        String q3 = "4.015 * 100=";
        String q4 = "303.1 / 1000=";
        NumberFormat percent = NumberFormat.getPercentInstance();     //建立百分比格式化用
        percent.setMaximumFractionDigits(5);
        double v = 0.06 + 0.01;
        System.out.println(q1 + v + "==" + percent.format(v));
        System.out.println(q2 + (1.0 - 0.42));
        System.out.println(q3 + (4.015 * 100));
        System.out.println(q4 + (303.1 / 1000));
        System.out.println("====================LINE====================");

        BigDecimal addend = new BigDecimal(0.06);
        BigDecimal augend = new BigDecimal(0.01);
        BigDecimal result = addend.add(augend);
        System.out.println(q1 + result.doubleValue() + "==" + percent.format(v));

        BigDecimal minuend = new BigDecimal(1.0);
        BigDecimal subtrahend = new BigDecimal(0.42);
        result = minuend.subtract(subtrahend);
        System.out.println(q2 + result.doubleValue());

        BigDecimal multiplicand = new BigDecimal(4.015);
        BigDecimal multiplicator = new BigDecimal(100);
        result = multiplicand.multiply(multiplicator);
        System.out.println(q3 + result.doubleValue());

        BigDecimal dividend = new BigDecimal(303.1);
        BigDecimal divisor = new BigDecimal(1000);
        int scale = 10;
        result = dividend.divide(divisor, scale, RoundingMode.HALF_UP);
        System.out.println(q4 + result.doubleValue());

    }

}

输出:

0.06 + 0.01 =0.06999999999999999==7%
1.0 - 0.42=0.5800000000000001
4.015 * 100=401.49999999999994
303.1 / 1000=0.30310000000000004
====================LINE====================
0.06 + 0.01 =0.06999999999999999==7%
1.0 - 0.42=0.5800000000000001
4.015 * 100=401.49999999999994
303.1 / 1000=0.3031

 

运行结果出现这种:
0.06999999999999999
0.5800000000000001
401.49999999999994
0.30310000000000004
你认为你看错了,但结果却是是这样的。
问题在哪里呢?
原因在于我们的计算机是二进制的。浮点数没有办法是用二进制进行精确表示。
我们的CPU表示浮点数由两个部分组成:指数和尾数,这样的表示方法一般都会失去一定的精确度,有些浮点数运算也会产生一定的误差。
如:2.4的二进制表示并非就是精确的2.4。
反而最为接近的二进制表示是 2.3999999999999999。
浮点数的值实际上是由一个特定的数学公式计算得到的。

其实java的float只能用来进行科学计算或工程计算,在大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。
在使用BigDecimal类来进行计算的时候,主要分为以下步骤:

1、用float或者double变量构建BigDecimal对象。

2、通过调用BigDecimal的加,减,乘,除等相应的方法进行算术运算。

3、把BigDecimal对象转换成float,double,int等类型。
一般来说,可以使用BigDecimal的构造方法或者静态方法的valueOf()方法把基本类型的变量构建成BigDecimal对象。

BigDecimal b1 = new BigDecimal(Double.toString(0.48));
BigDecimal b2 = BigDecimal.valueOf(0.48);

 

 

Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。
双精度浮点型变量double可以处理16位有效数
在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,
在商业计算中要用java.math.BigDecimal。
BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。
构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。

BigDecimal一共有4个构造方法
BigDecimal(int) 创建一个具有参数所指定整数值的对象。
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。
BigDecimal 的运算方式 不支持 + - * / 这类的运算 它有自己的运算方法
BigDecimal add(BigDecimal augend) 加法运算
BigDecimal subtract(BigDecimal subtrahend) 减法运算
BigDecimal multiply(BigDecimal multiplicand) 乘法运算
BigDecimal divide(BigDecimal divisor) 除法运算
   BigDecimal volumn = new BigDecimal("1");
   volumn = volumn.add(new BigDecimal("2"));
输出结果:3

格式化及例子编辑
由于NumberFormat类的format()方法可以使用BigDecimal对象作为其参数,可以利用BigDecimal对超出16位有效数字的货币值,百分值,以及一般数值进行格式化控制。
以利用BigDecimal对货币和百分比格式化为例。
首先,创建BigDecimal对象,进行BigDecimal的算术运算后,分别建立对货币和百分比格式化的引用,最后利用BigDecimal对象作为format()方法的参数,输出其格式化的货币值和百分比。

BigDecimal bigLoanAmount = new BigDecimal("具体数值");   //创建BigDecimal对象
BigDecimal bigInterestRate = new BigDecimal("具体数值");
BigDecimal bigInterest = bigLoanAmount.multiply(bigInterestRate); //BigDecimal运算
NumberFormat currency = NumberFormat.getCurrencyInstance();    //建立货币格式化引用
NumberFormat percent = NumberFormat.getPercentInstance();     //建立百分比格式化用
percent.setMaximumFractionDigits(3);               //百分比小数点最多3位
//利用BigDecimal对象作为参数在format()中调用货币和百分比格式化
System.out.println("Loan amount:\t" + currency.format(bigLoanAmount));
System.out.println("Interest rate:\t" + percent.format(bigInterestRate));
System.out.println("Interest:\t" + currency.format(bigInterest));
Loan amount:  ¥129,876,534,219,876,523.12
Interest rate: 8.765%
Interest:  ¥11,384,239,549,149,661.69
常见用法:
初始化 BigDecimal a= new BigDecimal("1.35");
对数值取值:
a.setScale(1,BigDecimal.ROUND_DOWN);
取一位小数,直接删除后面多余位数,故取值1.3.
a.setScale(1,BigDecimal.ROUND_UP);
取一位小数,删除后面位数,进一位,故取值1.4.
a.setScale(1,BigDecimal.ROUND_HALF_UP);
取一位小数,四舍五入,故取值1.4.
a.setScale(1,BigDecimal.ROUND_HALF_DOWN);
取一位小数,四舍五入,同上,故取值1.4.

http://baike.baidu.com/link?url=mm_3A7ifKIS0lDmiLyECVioqAbhNkSFfcNEor8ouSjxnbr-7_HqOwveXgt7xZOQA6tviAahv7i6ok3DPwrR5BekRtkjsxFD1SO079RdgIdC

public class Arith {
    /**
     * 提供精确加法计算的add方法
     * @param value1 被加数
     * @param value2 加数
     * @return 两个参数的和
     */
    public static double add(double value1,double value2){
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return b1.add(b2).doubleValue();
    }

    /**
     * 提供精确减法运算的sub方法
     * @param value1 被减数
     * @param value2 减数
     * @return 两个参数的差
     */
    public static double sub(double value1,double value2){
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 提供精确乘法运算的mul方法
     * @param value1 被乘数
     * @param value2 乘数
     * @return 两个参数的积
     */
    public static double mul(double value1,double value2){
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 提供精确的除法运算方法div
     * @param value1 被除数
     * @param value2 除数
     * @param scale 精确范围
     * @return 两个参数的商
     * @throws IllegalAccessException
     */
    public static double div(double value1,double value2,int scale) throws IllegalAccessException{
        //如果精确范围小于0,抛出异常信息
        if(scale<0){
            throw new IllegalAccessException("精确度不能小于0");
        }
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return b1.divide(b2, scale).doubleValue();
    }
}

 

时间: 2024-09-24 01:17:17

BigDecimal 专题的相关文章

Java 版的 Ruby 解释器 JRuby 1.7.14 发布_ruby专题

JRuby 1.7.14 发布 ,此版本现已提供下载: http://www.jruby.org/download JRuby 1.7 主要是为了兼容 Ruby 1.9.3 版本,改进记录如下: 解决了 30 个 issues 修复了 Jar 文件源潜在的内存泄漏问题 因为在 Rails 应用启动比较慢,所以默认禁用 invokedynamic load/require 内部重构和简化 解决了一些兼容性问题 1.7.14 修复的 bug: #1923 - String#start_with? r

Swift语法专题十二——方法

Swift讲解专题十二--方法 一.引言         方法只是一个术语,其实就是将函数与特定的类型结合,类.结构体.枚举都可以定义方法,方法又分为实例方法和类型方法,类型方法类似于Objective-C中的类方法.Swift和Objective-C的一大不同是,Objective-C只有在类中可以定义方法. 二.实例方法基础         实例方法的语法和函数完全一致,其和具体类型的实例所关联,实例方法在调用时由类型的实例点语法进行调用来完成一些功能模块.示例如下: class Math

SEO优化人员是否知道标签与栏目、专题、关键词之间的区别

摘要: 相比网站的关键词我们对文章标签的关注实在太少,不知道作为SEO优化人员的你是否知道标签与栏目.专题.关键词之间的区别?也许你会认为这是无关紧要的事情,如果是这样的话只能 相比网站的关键词我们对文章标签的关注实在太少,不知道作为SEO优化人员的你是否知道标签与栏目.专题.关键词之间的区别?也许你会认为这是无关紧要的事情,如果是这样的话只能说你是一个不善于思考问题的人,永远成不一个真正的SEO,因为SEO本身就是一个需要注重细节的职业.笔者发现现在几乎所有的文章都支持添加标签的功能,为什么一

PS婚纱照处理 Photoshop婚片美化、效果渲染专题教程

 三联教程为大家整理PS婚纱照处理专题教程   PS婚纱照处理 Photoshop婚片美化.效果渲染专题教程:专题列表 Photoshop打造古典青绿色外景婚片教程 简介:图片色彩构成比较简单,以绿色和红色为主.调色也较为简单,可直接用调色工具调出自己想要的颜色.也可以用通道等来调色.主色调好后,局部再加上光晕,增强画面的高光.    PhotoShop调色教程:给外景婚纱片调出淡黄绿色调效果 简介:介绍用PhotoShop给外景婚纱照片调出淡黄绿色调效果,主要用曲线.色相饱和度.可选颜色.色彩

Swift语法专题四——字符串与字符

Swift解读专题四--字符串与字符 一.引言         Swift中提供了String类型与Characters类型来处理字符串和字符数据,Swift中的String类型除了提供了许多方便开发者使用的方法外,还可以与Foundation框架的NSString类进行转换,使用起来十分方便. 二.String基础         在Swift中,使用双引号来定义字符串,开发者可以通过如下代码来创建一个字符串常量: let str = "Hello, playground" 可以通过

专题页设计技巧浅谈

  先以CP设计的的这个奥运专题为例分析专题设计中常遇到的一些问题. 这个页面存在的问题很多,我们来一个个分析. 首先第一个问题首屏高度: 分析一下常见分辨率及浏览器下高度数据: 在window XP常见分辨率1024×768下我们除掉任务栏,浏览器菜单栏以及状态栏后剩下的网页首屏高度平均值是584. Win7下是574.在window XP常见分辨率1440×900下我们除掉任务栏,浏览器菜单栏以及状态栏后剩下的网页首屏高度平均值是716.Win7下是706. 综合上面表中个分辨率及浏览器下的

Ubuntu Linux专题

Ubuntu 14.04中用Chrome浏览网页内容显示正常但是Tab显示乱码 Ubuntu 14.04安装mysq时报错问题 Ubuntu 12.04 创建用户失败如何解决 ubuntu安装软件提示无法打开锁文件 /var/lib/dpkg/lock 解决Ubuntu或Fedora虚拟机重启网络时报错问题 如何在ubuntu下创建桌面快捷方式 在ubuntu主线版本下的/var/cache/apt/archives文件夹说明:系统 ubuntu系统播放视频时黑屏的问题 Ubuntu及VMwar

专题一——Swift2.2语言预览

专题一--Swift2.2语言预览 一.引言         本系列专题是我通过阅读Swift2.2语言开发文档,翻译总结加上自己的理解整理而成.其中大部分结构和内容都来自开发文档,有疏漏和错误之处,还望更多朋友指出,共同交流进步,我的QQ:316045346. 二.从HelloWorld开始         在学习很多编程语言时,都是从HelloWorld入门,下面代码就是一个完整的HelloWorld程序: ? 1 print("Hello, World!") 分析上面代码,可以发

Community Server专题三:HttpModule

server 从专题三开始分析Community Server的一些具体的技术实现,根据IIS对请求的处理流程,从HttpModule& HttpHandler切入话题,同时你也可以通过一系列的专题了解CS的运行过程,不只如此,所有的.Net 1.1 构架的Web App都是以同样的顺序执行的. 先了解一下IIS系统.它是一个程序,负责对网站的内容进行管理并且处理对客户的请求做出反应.当用户对一个页面提出请求时,IIS做如下反应(不考虑权限问题): 1.把对方请求的虚拟路径转换成物理路径 2.根