Java中bigdecimal Java之BigDecimal详解

一、BigDeci***l概述java.***th包中提供的API类BigDeci***l用于对超过16个有效位的数字执行精确运算。双精度浮点变量Double可以处理16位有效数,但在实际应用中,可能需要运算和处理更大或更小的数。对于那些不需要精确计算精度的数字,一般我们可以直接使用Float和Double处理...

一、BigDeci***l概述

java.***th包中提供的API类BigDeci***l用于对超过16个有效位的数字执行精确运算。双精度浮点变量Double可以处理16位有效数,但在实际应用中,可能需要运算和处理更大或更小的数。对于那些不需要精确计算精度的数字,一般我们可以直接使用Float和Double处理,但是Double.valueOf(String)和Float.valueOf(String)会损失精度。所以在开发中,如果需要精确计算的结果,就必须使用BigDeci***l类来操作。

BigDeci***l创建的是一个对象,所以不能用+、-、*、/等传统的算术运算符直接对其对象进行数**算,而必须调用其对应的方法。方法中的参数也必须是BigDeci***l的对象。构造函数是类的一种特殊方法,专门用来创建对象,尤其是带参数的对象。

二、BigDeci***l常见构造函数

2.1.通用构造函数

BigDeci***l(int) 创建一个具有参数所指定整数值的对象BigDeci***l(double) 创建一个具有参数所指定双精度值的对象BigDeci***l(long) 创建一个具有参数所指定长整数值的对象BigDeci***l(String) 创建一个具有参数所指定以字符串表示的数值的对象

2.2.使用中的问题分析

使用示例:

BigDeci***l a =new BigDeci***l(0.1); System.out.println("a values is:"+a); System.out.println("====================="); BigDeci***l b =new BigDeci***l("0.1"); System.out.println("b values is:"+b);

结果示例:

a values is:0.1000000000000000055511151231257827021181583404541015625=====================b values is:0.1

原因分析:

1)具有双参数类型的构造方法的结果是不可预测的。有人可能会认为用Java写newBigDeci***l(0.1)创建的BigDeci***l正好等于0.1(非定标值1,其小数位数为1),但实际上等于0.1000000000000005这是因为0.1不能精确表示为double(或者在这种情况下,不能表示为任意有限长度的二进制小数)。这样,传入构造函数的值不会正好等于0.1(虽然表面上等于这个值)。

2)2)字符串构造方法是完全可以预测的:编写新的BigDeci***l ("0.1 ")将创建一个BigDeci***l,它正好等于预期的0.1。所以相比较而言,通常建议先用字符串构造法。

3)当double必须作为BigDeci***l的源时,请注意这种构造方法提供了准确的转换;它不会提供与以下操作相同的结果:首先使用Double.toString(Double)方法,然后使用BigDeci***l(String)构造方法将double转换为字符串。要获得结果,请使用静态valueOf(double)方法。

三。BigDeci***l常用方法详解

3.1.常用方法

add(BigDeci***l) BigDeci***l对象中的值相加,返回BigDeci***l对象subtract(BigDeci***l) BigDeci***l对象中的值相减,返回BigDeci***l对象multiply(BigDeci***l) BigDeci***l对象中的值相乘,返回BigDeci***l对象divide(BigDeci***l) BigDeci***l对象中的值相除,返回BigDeci***l对象toString() 将BigDeci***l对象中的值转换成字符串doubleValue() 将BigDeci***l对象中的值转换成双精度数floatValue() 将BigDeci***l对象中的值转换成单精度数longValue() 将BigDeci***l对象中的值转换成长整数intValue() 将BigDeci***l对象中的值转换成整数

3.2.BigDeci***l大小比较

在java中,BigDeci***l的compareTo方法一般用于比较BigDeci***l的大小。

int a = bigdemical.compareTo(bigdemical2)

返回结果分析:

a = -1,表示bigdemical小于bigdemical2;a = 0,表示bigdemical等于bigdemical2;a = 1,表示bigdemical大于bigdemical2;

例如:A大于等于b。

new bigdemica(a).compareTo(new bigdemical(b)) >= 0

四。BigDeci***l格式

因为NumberFor***t类的for***t()方法可以使用BigDeci***l对象作为其参数,所以可以使用BigDeci***l来格式化货币值、百分比值和超过16位有效数字的通用数值。

以BigDeci***l对货币和百分比的格式为例。首先创建一个BigDeci***l对象,在执行BigDeci***l的算术运算后,分别建立对货币和百分比格式的引用。最后使用BigDeci***l对象作为for***t()方法的参数,输出其格式化后的货币值和百分比。

NumberFor***t currency = NumberFor***t.getCurrencyInstance(); //建立货币格式化引用 NumberFor***t percent = NumberFor***t.getPercentInstance(); //建立百分比格式化引用 percent.setMaximumFractionDigits(3); //百分比小数点最多3位 BigDeci***l loanAmount = new BigDeci***l("15000.48"); //贷款金额 BigDeci***l interestRate = new BigDeci***l("0.008"); //利率 BigDeci***l interest = loanAmount.multiply(interestRate); //相乘 System.out.println("贷款金额:t" + currency.for***t(loanAmount)); System.out.println("利率:t" + percent.for***t(interestRate)); System.out.println("利息:t" + currency.for***t(interest));

结果:

贷款金额: ¥15,000.48 利率: 0.8% 利息: ¥120.00

BigDeci***l格式将2保留为十进制数,如果不足,则添加0:

public class NumberFor***t {public static void ***in(String[] s){System.out.println(for***tToNumber(new BigDeci***l("3.435")));System.out.println(for***tToNumber(new BigDeci***l(0)));System.out.println(for***tToNumber(new BigDeci***l("0.00")));System.out.println(for***tToNumber(new BigDeci***l("0.001")));System.out.println(for***tToNumber(new BigDeci***l("0.006")));System.out.println(for***tToNumber(new BigDeci***l("0.206"))); }/** * @desc 1.0~1之间的BigDeci***l小数,格式化后失去前面的0,则前面直接加上0。 * 2.传入的参数等于0,则直接返回字符串"0.00" * 3.大于1的小数,直接格式化返回字符串 * @param obj传入的小数 * @return */public static String for***tToNumber(BigDeci***l obj) {Deci***lFor***t df = new Deci***lFor***t("#.00");if(obj.compareTo(BigDeci***l.ZERO)==0) {return "0.00";}else if(obj.compareTo(BigDeci***l.ZERO)>0&&obj.compareTo(new BigDeci***l(1))<0){return "0"+df.for***t(obj).toString();}else {return df.for***t(obj).toString();}}}

结果是:

3.440.000.000.000.010.21

动词 (verb的缩写)BigDeci***l的常见异常

5.1.除法有例外。

java.lang.ArithmeticException: Non-terminating deci***l expansion; no exact representable deci***l result

原因分析:

用BigDeci***l的divide方法进行除法运算时,当出现无限循环小数时,会抛出异常:java.lang.arithmeticException:非终止小数展开;没有精确可表示的十进制结果。

解决方法:

divide方法设置精确的小数点,例如divide(xxxxx,2)

不及物动词BigDeci***l汇总

6.1.摘要

在需要精确的小数计算时再使用BigDeci***l,BigDeci***l的性能比double和float差,在处理庞大,复杂的运算时尤为明显。故一般精度的计算没必要使用BigDeci***l。尽量使用参数类型为String的构造函数。BigDeci***l都是不可变的(immutable)的, 在进行每一次四则运算时,都会产生一个新的对象 ,所以在做加减乘除运算时要记得要保存操作后的值。

6.2.推荐工具

package com.vivo.ars.util;import java.***th.BigDeci***l;/** * 用于高精确处理常用的数**算 */public class ArithmeticUtils { //默认除法运算精度 private static final int DEF_DIV_SCALE = 10; /** * 提供精确的加法运算 * * @param v1 被加数 * @param v2 加数 * @return 两个参数的和 */ public static double add(double v1, double v2) { BigDeci***l b1 = new BigDeci***l(Double.toString(v1)); BigDeci***l b2 = new BigDeci***l(Double.toString(v2)); return b1.add(b2).doubleValue(); } /** * 提供精确的加法运算 * * @param v1 被加数 * @param v2 加数 * @return 两个参数的和 */ public static BigDeci***l add(String v1, String v2) { BigDeci***l b1 = new BigDeci***l(v1); BigDeci***l b2 = new BigDeci***l(v2); return b1.add(b2); } /** * 提供精确的加法运算 * * @param v1 被加数 * @param v2 加数 * @param scale 保留scale 位小数 * @return 两个参数的和 */ public static String add(String v1, String v2, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDeci***l b1 = new BigDeci***l(v1); BigDeci***l b2 = new BigDeci***l(v2); return b1.add(b2).setScale(scale, BigDeci***l.ROUND_HALF_UP).toString(); } /** * 提供精确的减法运算 * * @param v1 被减数 * @param v2 减数 * @return 两个参数的差 */ public static double sub(double v1, double v2) { BigDeci***l b1 = new BigDeci***l(Double.toString(v1)); BigDeci***l b2 = new BigDeci***l(Double.toString(v2)); return b1.subtract(b2).doubleValue(); } /** * 提供精确的减法运算。 * * @param v1 被减数 * @param v2 减数 * @return 两个参数的差 */ public static BigDeci***l sub(String v1, String v2) { BigDeci***l b1 = new BigDeci***l(v1); BigDeci***l b2 = new BigDeci***l(v2); return b1.subtract(b2); } /** * 提供精确的减法运算 * * @param v1 被减数 * @param v2 减数 * @param scale 保留scale 位小数 * @return 两个参数的差 */ public static String sub(String v1, String v2, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDeci***l b1 = new BigDeci***l(v1); BigDeci***l b2 = new BigDeci***l(v2); return b1.subtract(b2).setScale(scale, BigDeci***l.ROUND_HALF_UP).toString(); } /** * 提供精确的乘法运算 * * @param v1 被乘数 * @param v2 乘数 * @return 两个参数的积 */ public static double mul(double v1, double v2) { BigDeci***l b1 = new BigDeci***l(Double.toString(v1)); BigDeci***l b2 = new BigDeci***l(Double.toString(v2)); return b1.multiply(b2).doubleValue(); } /** * 提供精确的乘法运算 * * @param v1 被乘数 * @param v2 乘数 * @return 两个参数的积 */ public static BigDeci***l mul(String v1, String v2) { BigDeci***l b1 = new BigDeci***l(v1); BigDeci***l b2 = new BigDeci***l(v2); return b1.multiply(b2); } /** * 提供精确的乘法运算 * * @param v1 被乘数 * @param v2 乘数 * @param scale 保留scale 位小数 * @return 两个参数的积 */ public static double mul(double v1, double v2, int scale) { BigDeci***l b1 = new BigDeci***l(Double.toString(v1)); BigDeci***l b2 = new BigDeci***l(Double.toString(v2)); return round(b1.multiply(b2).doubleValue(), scale); } /** * 提供精确的乘法运算 * * @param v1 被乘数 * @param v2 乘数 * @param scale 保留scale 位小数 * @return 两个参数的积 */ public static String mul(String v1, String v2, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDeci***l b1 = new BigDeci***l(v1); BigDeci***l b2 = new BigDeci***l(v2); return b1.multiply(b2).setScale(scale, BigDeci***l.ROUND_HALF_UP).toString(); } /** * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 * 小数点以后10位,以后的数字四舍五入 * * @param v1 被除数 * @param v2 除数 * @return 两个参数的商 */ public static double div(double v1, double v2) { return div(v1, v2, DEF_DIV_SCALE); } /** * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 * 定精度,以后的数字四舍五入 * * @param v1 被除数 * @param v2 除数 * @param scale 表示表示需要精确到小数点以后几位。 * @return 两个参数的商 */ public static double div(double v1, double v2, int scale) { if (scale < 0) { throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDeci***l b1 = new BigDeci***l(Double.toString(v1)); BigDeci***l b2 = new BigDeci***l(Double.toString(v2)); return b1.divide(b2, scale, BigDeci***l.ROUND_HALF_UP).doubleValue(); } /** * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 * 定精度,以后的数字四舍五入 * * @param v1 被除数 * @param v2 除数 * @param scale 表示需要精确到小数点以后几位 * @return 两个参数的商 */ public static String div(String v1, String v2, int scale) { if (scale < 0) { throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDeci***l b1 = new BigDeci***l(v1); BigDeci***l b2 = new BigDeci***l(v1); return b1.divide(b2, scale, BigDeci***l.ROUND_HALF_UP).toString(); } /** * 提供精确的小数位四舍五入处理 * * @param v 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 */ public static double round(double v, int scale) { if (scale < 0) { throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDeci***l b = new BigDeci***l(Double.toString(v)); return b.setScale(scale, BigDeci***l.ROUND_HALF_UP).doubleValue(); } /** * 提供精确的小数位四舍五入处理 * * @param v 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 */ public static String round(String v, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDeci***l b = new BigDeci***l(v); return b.setScale(scale, BigDeci***l.ROUND_HALF_UP).toString(); } /** * 取余数 * * @param v1 被除数 * @param v2 除数 * @param scale 小数点后保留几位 * @return 余数 */ public static String re***inder(String v1, String v2, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDeci***l b1 = new BigDeci***l(v1); BigDeci***l b2 = new BigDeci***l(v2); return b1.re***inder(b2).setScale(scale, BigDeci***l.ROUND_HALF_UP).toString(); } /** * 取余数 BigDeci***l * * @param v1 被除数 * @param v2 除数 * @param scale 小数点后保留几位 * @return 余数 */ public static BigDeci***l re***inder(BigDeci***l v1, BigDeci***l v2, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } return v1.re***inder(v2).setScale(scale, BigDeci***l.ROUND_HALF_UP); } /** * 比较大小 * * @param v1 被比较数 * @param v2 比较数 * @return 如果v1 大于v2 则 返回true 否则false */ public static boolean compare(String v1, String v2) { BigDeci***l b1 = new BigDeci***l(v1); BigDeci***l b2 = new BigDeci***l(v2); int bj = b1.compareTo(b2); boolean res; if (bj > 0) res = true; else res = false; return res; }}

本文来自又何必自找失落╮投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/629650.html

打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
() 0
上一篇 07-11
下一篇 07-11

相关推荐

  • java项目开发案例经典 java初学者简易小程序

    项目–吃货联盟一、项目准备:1.开发环境:JDK1.8IntelliJ IDEA2.技术要点分析:能理解程序基本概念 – 程序会使用变量、数据类型会使用顺序、选择、循环、跳转语句编写程序会使用数组3.任务描述:只要动动手指,就能送餐上门。“网上订餐受到现代人的青睐。现在,开发了一个

    2023-07-28 08:47:01
    708 0
  • java创建数组的几种方式 java编写图形界面程序

    数组是一组具有相同数据类型的数据。作为对象,new关键字允许用于内存分配。首先,熟悉一维数组的创建和使用。有两种方法可以声明一维数组:元素类型数组名称[];元素类型[]数组名称;元素类型决定数组的数据类型,在java中可以是任意数据类型,声明一个一维数组,比如int arr

    2023-07-27 04:07:01
    981 0
  • 如何安装java运行环境 java环境配置教程

    手动安装可以让用户更好地控制Java运行时环境。使用Linux发行版的包管理工具很容易安装Java包。但是,有时候需要手动安装Java。这对于Tomcat或JBoss等基于Java的应用服务器的管理员来说尤其重要。许多开源和专有软件产品依赖于这些服务。还是开发人员运行时套件?Java虚拟机(

    2023-07-26 08:27:01
    539 0
  • java是什么软件有什么作用 深入解析Java编程语言

    很多人或多或少和我一样。当我偶然在电视上看到程序员往电脑里敲一串代码的时候,我会忍不住惊叹他们,想象自己有一天也能这样。是的,有一天你也可以这样做!我们来看看到底什么是J***A?为什么学习?学习有什么用?让我给你看看2009年的计算机语言排名1。什么是JavaJava是一

    2023-07-26 04:56:01
    150 0

评论列表

联系我们

在线咨询: QQ交谈

邮件:admin@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信