`
竹临仙
  • 浏览: 38132 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

BigDecimal 的学习

 
阅读更多
package com.util;

import java.math.BigDecimal;


/**
*
*
BigDecimal(String)是把一个以String表示的BigDecimal对象构造为BigDecimal对象实例。
习惯上,对于浮点数我们都会定义为double或float,但BigDecimal API文档中对于BigDecimal(double)有这么一段话:
Note: the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .10000000000000000555111512312578 27021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances notwithstanding.
The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(".1") is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one
下面对这段话做简单解释:
注意:这个构造器的结果可能会有不可预知的结果。有人可能设想new BigDecimal(.1)等于.1是正确的,但它实际上是等于.1000000000000000055511151231257827021181583404541015625,这就是为什么.1不能用一个 double精确表示的原因,因此,这个被放进构造器中的长值并不精确的等于.1,尽管外观看起来是相等的。
然而(String)构造器,则完全可预知的,new BigDecimal(“.1”)如同期望的那样精确的等于.1,因此,(String)构造器是被优先推荐使用的。
看下面的结果:
      System.out.println(new BigDecimal(123456789.02).toString());
      System.out.println(new BigDecimal("123456789.02").toString());
输出为:
123456789.01999999582767486572265625
123456789.02
现在我们知道,如果需要精确计算,非要用String来够造BigDecimal不可!
实现方案
现在我们已经知道怎么解决这个问题了,原则上是使用BigDecimal(String)构造器,我们建议,在商业应用开发中,涉及金额等浮点数计算的数据,全部定义为String,数据库中可定义为字符型字段,在需要使用这些数据进行运算的时候,使用BigDecimal(String)构造 BigDecimal对象进行运算,保证数据的精确计算。同时避免了科学记数法的出现。如果科学记数表示法在应用中不是一种负担的话,可以考虑定义为浮点类型。
这里我们提供了一个工具类,定义浮点数的加、减、乘、除和四舍五入等运算方法。以供参考。
*
*/
public class MathExtend

{

// 默认除法运算精度

private static final int DEFAULT_DIV_SCALE = 10;

/**
*
* 提供精确的加法运算。
*
* @param v1
*
* @param v2
*
* @return 两个参数的和
*/

public static double add(double v1, double v2)

{

BigDecimal b1 = new BigDecimal(Double.toString(v1));

BigDecimal b2 = new BigDecimal(Double.toString(v2));

return b1.add(b2).doubleValue();

}

/**
*
* 提供精确的加法运算
*
* @param v1
*
* @param v2
*
* @return 两个参数数学加和,以字符串格式返回
*/

public static String add(String v1, String v2)

{

BigDecimal b1 = new BigDecimal(v1);

BigDecimal b2 = new BigDecimal(v2);

return b1.add(b2).toString();

}

/**
*
* 提供精确的减法运算。
*
* @param v1
*
* @param v2
*
* @return 两个参数的差
*/

public static double subtract(double v1, double v2)

{

BigDecimal b1 = new BigDecimal(Double.toString(v1));

BigDecimal b2 = new BigDecimal(Double.toString(v2));

return b1.subtract(b2).doubleValue();

}

/**
*
* 提供精确的减法运算
*
* @param v1
*
* @param v2
*
* @return 两个参数数学差,以字符串格式返回
*/

public static String subtract(String v1, String v2)

{

BigDecimal b1 = new BigDecimal(v1);

BigDecimal b2 = new BigDecimal(v2);

return b1.subtract(b2).toString();

}

/**
*
* 提供精确的乘法运算。
*
* @param v1
*
* @param v2
*
* @return 两个参数的积
*/

public static double multiply(double v1, double v2)

{

BigDecimal b1 = new BigDecimal(Double.toString(v1));

BigDecimal b2 = new BigDecimal(Double.toString(v2));

return b1.multiply(b2).doubleValue();

}

/**
*
* 提供精确的乘法运算
*
* @param v1
*
* @param v2
*
* @return 两个参数的数学积,以字符串格式返回
*/

public static String multiply(String v1, String v2)

{

BigDecimal b1 = new BigDecimal(v1);

BigDecimal b2 = new BigDecimal(v2);

return b1.multiply(b2).toString();

}

/**
*
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
*
* 小数点以后10位,以后的数字四舍五入,舍入模式采用ROUND_HALF_EVEN
*
* @param v1
*
* @param v2
*
* @return 两个参数的商
*/

public static double divide(double v1, double v2)

{

return divide(v1, v2, DEFAULT_DIV_SCALE);

}

/**
*
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
*
* 定精度,以后的数字四舍五入。舍入模式采用ROUND_HALF_EVEN
*
* @param v1
*
* @param v2
*
* @param scale
*            表示需要精确到小数点以后几位。
*
* @return 两个参数的商
*/

public static double divide(double v1, double v2, int scale)

{

return divide(v1, v2, scale, BigDecimal.ROUND_HALF_EVEN);

}

/**
*
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
*
* 定精度,以后的数字四舍五入。舍入模式采用用户指定舍入模式
*
* @param v1
*
* @param v2
*
* @param scale
*            表示需要精确到小数点以后几位
*
* @param round_mode
*            表示用户指定的舍入模式
*
* @return 两个参数的商
*/

public static double divide(double v1, double v2, int scale, int round_mode) {

if (scale < 0)

{

throw new IllegalArgumentException(
"The scale must be a positive integer or zero");

}

BigDecimal b1 = new BigDecimal(Double.toString(v1));

BigDecimal b2 = new BigDecimal(Double.toString(v2));

return b1.divide(b2, scale, round_mode).doubleValue();

}

/**
*
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
*
* 小数点以后10位,以后的数字四舍五入,舍入模式采用ROUND_HALF_EVEN
*
* @param v1
*
* @param v2
*
* @return 两个参数的商,以字符串格式返回
*/

public static String divide(String v1, String v2)

{

return divide(v1, v2, DEFAULT_DIV_SCALE);

}

/**
*
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
*
* 定精度,以后的数字四舍五入。舍入模式采用ROUND_HALF_EVEN
*
* @param v1
*
* @param v2
*
* @param scale
*            表示需要精确到小数点以后几位
*
* @return 两个参数的商,以字符串格式返回
*/

public static String divide(String v1, String v2, int scale)

{

return divide(v1, v2, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_EVEN);

}

/**
*
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
*
* 定精度,以后的数字四舍五入。舍入模式采用用户指定舍入模式
*
* @param v1
*
* @param v2
*
* @param scale
*            表示需要精确到小数点以后几位
*
* @param round_mode
*            表示用户指定的舍入模式
*
* @return 两个参数的商,以字符串格式返回
*/

public static String divide(String v1, String v2, int scale, int round_mode)

{

if (scale < 0)

{

throw new IllegalArgumentException(
"The scale must be a positive integer or zero");

}

BigDecimal b1 = new BigDecimal(v1);

BigDecimal b2 = new BigDecimal(v2);

return b1.divide(b2, scale, round_mode).toString();

}

/**
*
* 提供精确的小数位四舍五入处理,舍入模式采用ROUND_HALF_EVEN
*
* @param v
*            需要四舍五入的数字
*
* @param scale
*            小数点后保留几位
*
* @return 四舍五入后的结果
*/

public static double round(double v, int scale)

{

return round(v, scale, BigDecimal.ROUND_HALF_EVEN);

}

/**
*
* 提供精确的小数位四舍五入处理
*
* @param v
*            需要四舍五入的数字
*
* @param scale
*            小数点后保留几位
*
* @param round_mode
*            指定的舍入模式
*
* @return 四舍五入后的结果
*/

public static double round(double v, int scale, int round_mode)

{

if (scale < 0)

{

throw new IllegalArgumentException(
"The scale must be a positive integer or zero");

}

BigDecimal b = new BigDecimal(Double.toString(v));

return b.setScale(scale, round_mode).doubleValue();

}

/**
*
* 提供精确的小数位四舍五入处理,舍入模式采用ROUND_HALF_EVEN
*
* @param v
*            需要四舍五入的数字
*
* @param scale
*            小数点后保留几位
*
* @return 四舍五入后的结果,以字符串格式返回
*/

public static String round(String v, int scale)

{

return round(v, scale, BigDecimal.ROUND_HALF_EVEN);

}

/**
*
* 提供精确的小数位四舍五入处理
*
* @param v
*            需要四舍五入的数字
*
* @param scale
*            小数点后保留几位
*
* @param round_mode
*            指定的舍入模式
*
* @return 四舍五入后的结果,以字符串格式返回
*/

public static String round(String v, int scale, int round_mode)

{

if (scale < 0)

{

throw new IllegalArgumentException(
"The scale must be a positive integer or zero");

}

BigDecimal b = new BigDecimal(v);

return b.setScale(scale, round_mode).toString();

}
}
分享到:
评论

相关推荐

    javascript版BigDecimal类库

    JavaScript是一种广泛应用于Web开发的轻量级脚本语言,它在处理大整数或高精度浮点数时存在精度问题,这是因为JavaScript...通过学习和应用这个库,开发者可以更好地控制计算过程中的精度,提高代码的可靠性和健壮性。

    bigdecimal

    通过本文的学习,我们了解到了 `BigDecimal` 类的重要性及其在处理高精度计算中的作用。掌握 `BigDecimal` 的使用对于编写高质量的财务系统或其他对精度有要求的应用程序来说是非常必要的。希望本文能够帮助读者更好...

    MyEditTextApplication输入框BigDecimal计算价格

    在Android应用开发中,我们经常需要处理用户在输入框(EditText)中输入的数据,特别是涉及到货币计算时,精确的数值处理变得尤为重要。...开发者可以参考该项目来学习如何在实际项目中实现类似的高精度计算需求。

    BigDecimal-CPP-master.zip

    标题中的"BigDecimal-CPP-master.zip"表明这是一个与BigDecimal类实现相关的C++项目压缩包。BigDecimal是一种可以处理任意...通过学习和使用`BigDecimal`类,开发者可以避免浮点数精度问题,从而获得更准确的计算结果。

    java-BigInteger-BigDecimal类源码

    总之,`BigInteger`和`BigDecimal`是Java中处理大整数和高精度浮点数的关键工具,它们的源代码为我们提供了深入学习和定制这两个类的机会。理解并掌握这些类的使用能极大地提升在处理数学计算时的精确性和效率。

    BigInteger BigDecimal 使用

    在Java编程语言中,`BigInteger`和`BigDecimal`是两...在实际学习和使用时,可以查看这些源代码来理解这两个类的具体用法和应用场景。通过分析和调试代码,可以加深对大整数和高精度浮点数运算的理解,并提升编程技能。

    Java的数学运算处理类讲解代码(BigDecimal、Math、Random、DecimalFormat类全部操作方法API)

    该项目包含详细的代码示例和注释,涵盖了以下几个主要的数学计算处理类:BigDecimal、Math、Random和DecimalFormat。 适用人群: Java开发者:对于使用Java进行数学计算和处理的开发者。 学习者:对于想要了解Java...

    面试官:BigDecimal一定不会丢失精度吗?.zip

    计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料 计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料 计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料 计算机技术、IT咨询、人工智能AI理论介绍,...

    Java 中的 BigDecimal,你真的会用吗?.zip

    计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料计算机技术、IT咨询、人工智能AI理论介绍,学习...

    Calculator:BigDecimal类的便捷包装器,允许计算运算忽略乘和除零的影响

    在Java编程语言中,BigDecimal类是用于表示精确的十进制浮点数的类,它提供了...通过阅读源码,你可以学习到如何优雅地处理可能的数学运算异常,以及如何扩展BigDecimal的功能,提高其在实际项目中的可定制性和健壮性。

    基于springboot+策略模式 实现简单促销

    策略模式 基于springboot+策略模式 实现简单促销 //加法 BigDecimal result1 = num1.add(num2);...适用人群:学习不同技术领域的小白或进阶学习者;可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。

    数字格式化类与大数处理利用案例轻松学习Java语言PPT学习教案.pptx

    在学习过程中,可以尝试完成课后作业,如计算精确到小数点后30位的π值,并根据圆的半径计算面积;或者计算棋盘格子大米的总质量,这是一个典型的指数增长问题,可以用大数处理来解决。 总之,理解并熟练掌握Java中...

    calculadora-emjava:Uma后端参数实现了Matmaticas com BigDecimal

    在本项目"Calculadora-emjava"中,我们探讨了一个基于Java技术实现的数学计算后端。这个项目的主要目的是使用...同时,项目也涉及到了Web服务的开发、请求处理和响应生成,是学习Java后端开发的一个实用案例。

    Java_BigDecimalInterest:使用 BigDecimal 计算复利的简单程序。 摘自“Java How To Program, 10e, Early Objects”——第 8 章

    这个程序来源于《Java How To Program》的第10版,早期对象章节,它旨在帮助学习者理解如何在实际编程中应用BigDecimal进行复杂计算。 复利计算涉及到多次累加利息的过程,通常用公式表示为:A = P * (1 + r/n)^(nt...

    《深入浅出struts》 源代码

    源代码通常包含了书中所讲解的实际应用示例,便于读者理解和学习。 在提供的压缩包文件中,我们可以看到以下内容: 1. **win-compile.bat** 和 **linux-compile.sh**:这两个文件分别对应Windows和Linux平台的编译...

    BigNumber-源码.rar

    《深入剖析BigDecimal:Java中的大数运算实现》 在Java编程语言中,处理大数运算时,我们常常会遇到超出普通整型或浮点型表示范围的数字。为了解决这个问题,Java提供了一个名为`BigDecimal`的类,它是`java.math`...

    1.JavaSE基础学习笔记

    ### JavaSE基础学习笔记 #### 一、Java概述与历史 - **起源与发展**:Java最初由Sun Microsystems在1995年推出,后被Oracle公司收购并继续发展。Java经历了多个版本的发展,逐渐形成了Java SE(Standard Edition,...

    A Class for Creating a Trace Log(153KB)

    - "源码"表明提供的是可阅读和学习的代码,而非仅有的二进制执行文件。 - "资源"可能是指除了源代码之外,还有其他辅助文件,如Bitmap图像(Toolbar.bmp)或项目文件(Trace.dsp、Trace.dsw)。 从压缩包中的文件名...

    Java学习路线图.pdf

    - **String、BigDecimal**:深入学习字符串(String)的特性,以及BigDecimal类用于高精度计算。 5. **集合与异常**: - **集合框架**:理解Collection、List、Set、Map接口及其常见实现类,学习泛型和工具类的使用...

    超强常用的正则表达式2009

    正则表达式(Regular Expression,简称regex)是用于匹配字符串的一种模式,广泛应用于文本处理、数据验证、搜索和替换等场景。...通过不断地实践和学习,我们可以更灵活地运用这些工具,解决各种复杂的文本处理问题。

Global site tag (gtag.js) - Google Analytics