`
Scliu123
  • 浏览: 39968 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

JDK_实例(处理大数字)

阅读更多
package book.number;

import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * 第1.4节的计算Factorial的类中,我们限制了用户输入的n必须小于18,原因是,当n等于18时,
 * n!的值已经超过了范围最大的基本类型long能够表示的范围了,也就是说使用Java的基本数据类型在进行运算时会存在溢出问题。
 * 
 * 同样,在进行小数运算时,也会出现不精确的问题。请看下面一段代码:
 * code
 * 执行结果让人迷惑。
 * Java中的简单浮点数类型float和double不能够进行精确的运算,只能用来做科学计算或者是工程计算。
 * 不光是Java,在其它很多编程语言中也有这样的问题。在大多数情况下,计算的结果是准确的,
 * 但是多试几次(可以做一个循环)就可以试出类似上面的错误。
 * 这个问题相当严重,如果你有9.999999999999元,你的计算机是不会认为你可以购买10元的商品的。
 * 
 * 为了解决Java基本数据类型在运算时会出现的溢出和计算不精确的问题。
 * Java 提供了两个类BigInteger和BigDecimal,专门用于进行高精度运算
 * 凡是能用int 或float 做的事情,用BigInteger和BigDecimal也可以做,
 * 只是必须换用方法调用,而不是使用运算符。
 * 
 * 高精度整数BigInteger
 * BigInteger支持任意精度的整数,也就是说我们可精确表示任意大小的整数值;同时在运算过程中不会丢失任何信息;
 * 
 * 高精度浮点数BigDecimal
 * 它可以表示任意精度的小数,并对它们进行计算。
 * 由于 BigDecimal 对象是不可变的,这些方法中的每一个都会产生新的 BigDecimal 对象。
 * 因此,因为创建对象的开销,BigDecimal 不适合于大量的数学计算,但设计它的目的是用来精确地表示小数。
 */
public class BigNumber {

	//默认除法运算精度,即保留小数点多少位 
	private static final int DEFAULT_DIV_SCALE = 10;

	//这个类不能实例化 
	private BigNumber() {
	}

	/** 
	 * 提供精确的加法运算。 
	 * @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 double sub(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 double mul(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 double div(double v1, double v2) {
		return div(v1, v2, DEFAULT_DIV_SCALE);
	}

	/** 
	 * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 
	 * 定精度,以后的数字四舍五入。 
	 * @param v1 被除数 
	 * @param v2 除数 
	 * @param scale 表示需要精确到小数点以后几位。 
	 * @return 两个参数的商 
	 */
	public static double div(double v1, double v2, int scale) {
		if (scale < 0) {
			System.err.println("除法精度必须大于0!");
			return 0;
		}
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return (b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP)).doubleValue();
	}

	/**
	 * 计算Factorial阶乘!
	 * @param n		任意大于等于0的int
	 * @return     n!的值
	 */
	public static BigInteger getFactorial(int n) {
		if (n < 0) {
			System.err.println("n必须大于等于0!");
			return new BigInteger("-1");
		} else if (n == 0) {
			return new BigInteger("0");
		}
		//将数组换成字符串后构造BigInteger
		BigInteger result = new BigInteger("1");
		for (; n > 0; n--) {
			//将数字n转换成字符串后,再构造一个BigInteger对象,与现有结果做乘法
			result = result.multiply(new BigInteger(new Integer(n).toString()));
		}
		return result;
	}

	public static void main(String[] args) {

		//		如果我们编译运行下面这个程序会看到什么?
		System.out.println(0.05 + 0.01);
		System.out.println(1.0 - 0.42);
		System.out.println(4.015 * 100);
		System.out.println(123.3 / 100);
		//		0.060000000000000005
		//		0.5800000000000001
		//		401.49999999999994
		//		1.2329999999999999

		//计算阶乘,可以将n设得更大
		int n = 30;
		System.out.println("计算n的阶乘" + n + "! = " + BigNumber.getFactorial(n));

		//用double构造BigDecimal
		BigDecimal bd1 = new BigDecimal(0.1);
		System.out.println("(bd1 = new BigDecimal(0.1)) = " + bd1.toString());
		//用String构造BigDecimal
		BigDecimal bd2 = new BigDecimal("0.1");
		System.out.println("(bd2 = new BigDecimal(\"0.1\")) = "
				+ bd2.toString());

		BigDecimal bd3 = new BigDecimal("0.10");
		//equals方法比较两个BigDecimal对象是否相等,相等返回true,不等返回false
		System.out.println("bd2.equals(bd3) = " + bd2.equals(bd3));//false
		//compareTo方法比较两个BigDecimal对象的大小,相等返回0,小于返回-1,大于返回1。
		System.out.println("bd2.compareTo(bd3) = " + bd2.compareTo(bd3));//0

		//进行精确计算
		System.out.println("0.05 + 0.01 = " + BigNumber.add(0.05, 0.01));
		System.out.println("1.0 - 0.42 = " + BigNumber.add(1.0, 0.42));
		System.out.println("4.015 * 100 =" + BigNumber.add(4.015, 100));
		System.out.println("123.3 / 100 = " + BigNumber.add(123.3, 100));

		/**
		 * (1)BigInteger和BigDecimal都是不可变(immutable)的,在进行每一步运算时,都会产生一个新的对象,由于创建对象会引起开销,
		 * 它们不适合于大量的数学计算,应尽量用long,float,double等基本类型做科学计算或者工程计算。
		 * 设计BigInteger和BigDecimal的目的是用来精确地表示大整数和小数,使用于在商业计算中使用。
		 * (2)BigDecimal有4个够造方法,其中的两个用BigInteger构造,另一个是用double构造,还有一个使用String构造。
		 * 应该避免使用double构造BigDecimal,因为:有些数字用double根本无法精确表示,传给BigDecimal构造方法时就已经不精确了。
		 * 比如,new BigDecimal(0.1)得到的值是0.1000000000000000055511151231257827021181583404541015625。
		 * 使用new BigDecimal("0.1")得到的值是0.1。因此,如果需要精确计算,用String构造BigDecimal,避免用double构造,尽管它看起来更简单! 
		 * (3)equals()方法认为0.1和0.1是相等的,返回true,而认为0.10和0.1是不等的,结果返回false。
		 * 方法compareTo()则认为0.1与0.1相等,0.10与0.1也相等。所以在从数值上比较两个BigDecimal值时,应该使用compareTo()而不是 equals()。
		 * (4)另外还有一些情形,任意精度的小数运算仍不能表示精确结果。例如,1除以9会产生无限循环的小数 .111111...。
		 * 出于这个原因,在进行除法运算时,BigDecimal可以让您显式地控制舍入。
		 */

	}

}

 

分享到:
评论

相关推荐

    Java JDK实例宝典

    6 处理大数字 第4章 数组与集合 4. 1 使用Arrays 4. 2 求质数. 4. 3 动态调整数组长度 4. 4 矩阵 4. 5 ArrayList. Vector和LinkedList 4. 6 生成不重复的随机数序列 4. 7 自定义...

    java范例开发大全

    实例41 数字格式转换异常(NumberFornatException) 59 实例42 字符串索引越界异常(StringIndexOutBounds) 60 实例43 操作错误(UnsupportedOperationException) 60 4.2 运行时异常 61 实例44 找不到指定类时发生...

    Java范例开发大全 (源程序)

     实例41 数字格式转换异常(NumberFornatException) 59  实例42 字符串索引越界异常(StringIndexOutBounds) 60  实例43 操作错误(UnsupportedOperationException) 60  4.2 运行时异常 61  实例44 找不...

    java范例开发大全(pdf&源码)

    实例41 数字格式转换异常(NumberFornatException) 59 实例42 字符串索引越界异常(StringIndexOutBounds) 60 实例43 操作错误(UnsupportedOperationException) 60 4.2 运行时异常 61 实例44 找不到指定类时发生...

    Java范例开发大全(全书源程序)

    实例41 数字格式转换异常(NumberFornatException) 59 实例42 字符串索引越界异常(StringIndexOutBounds) 60 实例43 操作错误(UnsupportedOperationException) 60 4.2 运行时异常 61 实例44 找不到指定类...

    java范例开发大全源代码

     实例41 数字格式转换异常(NumberFornatException) 59  实例42 字符串索引越界异常(StringIndexOutBounds) 60  实例43 操作错误(UnsupportedOperationException) 60  4.2 运行时异常 61  实例44 ...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例002 把JDK工具包安装到指定磁盘 4 实例003 设置JDK的环境变量 6 实例004 验证Java开发环境 7 实例005 下载并安装JRE执行环境 8 实例006 编程输出星号组成的等腰三角形 9 1.2 开发工具 11 实例007 下载最新的...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    本书语言生动、通俗易懂、讲解细致,大部分章节都提供了多个例子,而且很多例子都是目前web开发中经常使用的功能,具有相当的实用价值。本书不仅可以作为java web开发的学习用书,还可以作为从事java web开发的...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part3

    本书语言生动、通俗易懂、讲解细致,大部分章节都提供了多个例子,而且很多例子都是目前web开发中经常使用的功能,具有相当的实用价值。本书不仅可以作为java web开发的学习用书,还可以作为从事java web开发的...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part4

    本书语言生动、通俗易懂、讲解细致,大部分章节都提供了多个例子,而且很多例子都是目前web开发中经常使用的功能,具有相当的实用价值。本书不仅可以作为java web开发的学习用书,还可以作为从事java web开发的...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part5

    本书语言生动、通俗易懂、讲解细致,大部分章节都提供了多个例子,而且很多例子都是目前web开发中经常使用的功能,具有相当的实用价值。本书不仅可以作为java web开发的学习用书,还可以作为从事java web开发的...

    Process-Data-In-Files-In-Parallel:并行添加大量包含数字的文件,并计算它们的总数。 使用了 JDK 5 并发执行器。使用了不变性模式。 用于共享访问的原子整数。 工厂模式用于通过同步安全地分发实例

    并行添加大量包含数字的文件,并计算它们的总数。 使用了 JDK 5 并发执行器。使用了不变性模式。 用于共享访问的原子整数。 工厂模式用于通过同步安全地分发实例。 要运行此演示,请使用FileSumUp.java的main方法...

    JAVA 2平台安全技术-结构,API设计和实现

    5.4.3 为JDK1.2而改进JDK1.1 安全管理器 100 第6章 对象的安全 106 6.1 安全异常 106 6.2 域和方法 107 6.3 静态域 107 6.4 私有对象状态和对象不变性 108 6.5 特权代码 109 6.6 连续性 110 6.7 内部类 111 6.8 本...

    Java优化编程(第2版)

    Java优化编程(第2版)通过丰富、完整、富有代表性的实例,展示了如何提升Java应用性能,并且给出了优化前与优化后的Java应用程序的性能差别,以实际的实例与数字告诉你,为什么不可以这么做,应该怎么做,深入分析...

    Java Web应用详解.张丽(带详细书签).pdf

    本书论述精准而深刻,程序实例丰富实用,不仅适用于数字媒体技术、计算机等相关专业的学生作为教材.廿可作为IT培训机构的培训教材,还可供广大JavaWeb程序员作为参考。 静态网页篇 第1章 开发环境安装及配置 1.1 ...

    Java开发技术大全(500个源代码).

    示例描述:本章演示如何开始使用JDK进行程序的开发。 HelloWorldApp.java 第一个用Java开发的应用程序。 firstApplet.java 第一个用Java开发的Applet小程序。 firstApplet.htm 用来装载Applet的网页文件 第2章 ...

    Java开发技术大全 电子版

    1.2.1JDK的安装4 1.2.2如何设置系统环境变量6 1.2.3编译命令的使用8 1.2.4解释执行命令的使用10 1.2.5UltraEdit的使用11 1.3一个简单的Java应用程序14 1.4一个简单的Java小程序16 1.5本章小结18 第2章Java...

Global site tag (gtag.js) - Google Analytics