热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java中处理大数据问题(BigInteger、BigDecimal)

原文转自:https:blog.csdn.netzhongkeleearticledetails52289163;http:www.cnblogs.c
原文转自:https://blog.csdn.net/zhongkelee/article/details/52289163;

 http://www.cnblogs.com/chenssy/ 

适用范围

使用BigInteger操作大整数(处理超出long整型范围的数据)
使用BigDecimal指定小数的保留位数

基础知识

对于二进制来说,最高位代表正负号,-0表示-128,+0表示0
32位系统int型4个字节:-(2的31次方) ~ (2的31次方) 减 1
最大负数:10000000 00000000 00000000 00000000
最大正数:01111111 11111111 11111111 11111111
0:                 00000000 00000000 00000000 00000000

64位系统同理,int型表示范围是:-(2的63次方) ~ (2的63次方) 减 1


具体内容

大数操作

正常情况下一个整数最多只能放在long类型之中,但是如果现在有如下的一个数字:
        1111111111111111111111111111111111111111111111111
根本就是无法保存的,所以为了解决这样的问题,在java中引入了两个大数的操作类:
        操作整型:BigInteger
        操作小数:BigDecimal
当然了,这些大数都会以字符串的形式传入。

BigInteger

        如果在操作的时候一个整型数据已经超过了整数的最大类型长度long的话,则此数据就无法装入,所以,此时要使用BigInteger类进行操作。


        BigInteger是在java.math包中。

代码示例:

[java]  view plain  copy
  1. package ustc.lichunchun.bigdataapi;  
  2.   
  3. import java.math.BigInteger;  
  4.   
  5. public class BigIntegerDemo1 {  
  6.   
  7.     public static void main(String[] args) {  
  8.         BigInteger bi1 = new BigInteger("123456789") ;  // 声明BigInteger对象  
  9.         BigInteger bi2 = new BigInteger("987654321") ;  // 声明BigInteger对象  
  10.         System.out.println("加法操作:" + bi2.add(bi1)) ;    // 加法操作  
  11.         System.out.println("减法操作:" + bi2.subtract(bi1)) ;   // 减法操作  
  12.         System.out.println("乘法操作:" + bi2.multiply(bi1)) ;   // 乘法操作  
  13.         System.out.println("除法操作:" + bi2.divide(bi1)) ; // 除法操作  
  14.         System.out.println("最大数:" + bi2.max(bi1)) ;  // 求出最大数  
  15.         System.out.println("最小数:" + bi2.min(bi1)) ;  // 求出最小数  
  16.         BigInteger result[] = bi2.divideAndRemainder(bi1) ; // 求出余数的除法操作  
  17.         System.out.println("商是:" + result[0] +   
  18.             ";余数是:" + result[1]) ;  
  19.     }  
  20. }  

发现divide()方法本身只是把最终的商保存下来了,但是这样的两个数字相除的时候肯定是无法整除,肯定存在余数,所以我们在上面代码中还用到了divideAndRemainder()方法来获得结果和余数。

BigDecimal

首先我们先来看如下代码示例:

1 public class Test_1 {
2     public static void main(String[] args) {
3         System.out.println(0.06+0.01);
4         System.out.println(1.0-0.42);
5         System.out.println(4.015*100);
6         System.out.println(303.1/1000);
7     }
8     
9 }

          运行结果如下。

         0.06999999999999999

         0.5800000000000001

         401.49999999999994

         0.30310000000000004

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

          其实javafloat只能用来进行科学计算或工程计算,在大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。

          在使用BigDecimal类来进行计算的时候,主要分为以下步骤:

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

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

             3、把BigDecimal对象转换成floatdoubleint等类型。

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

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

        对于常用的加,减,乘,除,BigDecimal类提供了相应的成员方法。

1 public BigDecimal add(BigDecimal value);                        //加法
2 public BigDecimal subtract(BigDecimal value);                   //减法 
3 public BigDecimal multiply(BigDecimal value);                   //乘法
4 public BigDecimal divide(BigDecimal value);                     //除法


     进行相应的计算后,我们可能需要将BigDecimal对象转换成相应的基本数据类型的变量,可以使用floatValue()doubleValue()等方法。

        使用此类可以完成大的小数操作,而且也可以使用此类进行精确的四舍五入,这一点在开发中经常使用。
        对于不需要任何准确计算精度的程序可以直接使用float或double完成,但是如果需要精确计算结果,则必须使用BigDecimal类。


代码示例:

[java]  view plain  copy
  1. package ustc.lichunchun.bigdataapi;  
  2.   
  3. import java.math.BigDecimal;  
  4.   
  5. public class BigDecimalDemo01 {  
  6.   
  7.     public static void main(String[] args) {  
  8.         System.out.println("加法运算:" + MyMath.round(MyMath.add(10.345,3.333),1)) ;  
  9.         System.out.println("减法运算:" + MyMath.round(MyMath.sub(10.345,3.333),3)) ;  
  10.         System.out.println("乘法运算:" + MyMath.round(MyMath.mul(10.345,3.333),4)) ;  
  11.         System.out.println("除法运算:" + MyMath.div(10.345,3.333,3)) ;  
  12.     }  
  13. }  
  14. class MyMath{  
  15.     public static double add(double d1,double d2){      // 进行加法计算  
  16.         BigDecimal b1 = new BigDecimal(d1) ;  
  17.         BigDecimal b2 = new BigDecimal(d2) ;  
  18.         return b1.add(b2).doubleValue() ;  
  19.     }  
  20.     public static double sub(double d1,double d2){      // 进行减法计算  
  21.         BigDecimal b1 = new BigDecimal(d1) ;  
  22.         BigDecimal b2 = new BigDecimal(d2) ;  
  23.         return b1.subtract(b2).doubleValue() ;  
  24.     }  
  25.     public static double mul(double d1,double d2){      // 进行乘法计算  
  26.         BigDecimal b1 = new BigDecimal(d1) ;  
  27.         BigDecimal b2 = new BigDecimal(d2) ;  
  28.         return b1.multiply(b2).doubleValue() ;  
  29.     }  
  30.     public static double div(double d1,double d2,int len){      // 进行除法计算  
  31.         BigDecimal b1 = new BigDecimal(d1) ;  
  32.         BigDecimal b2 = new BigDecimal(d2) ;  
  33.         return b1.divide(b2,len,BigDecimal.ROUND_HALF_UP).doubleValue() ;  
  34.     }  
  35.     public static double round(double d,int len){   // 进行四舍五入  
  36.         BigDecimal b1 = new BigDecimal(d) ;  
  37.         BigDecimal b2 = new BigDecimal(1) ; // 技巧  
  38.         return b1.divide(b2,len,BigDecimal.ROUND_HALF_UP).doubleValue() ;  
  39.     }  
  40. };  

提示:

1、一般在开发中很少遇到大数字的操作情况。
2、使用BigDecimal可以指定好四舍五入的精确位置。


推荐阅读
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 对象自省自省在计算机编程领域里,是指在运行时判断一个对象的类型和能力。dir能够返回一个列表,列举了一个对象所拥有的属性和方法。my_list[ ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • c# – UWP:BrightnessOverride StartOverride逻辑 ... [详细]
  • 本文探讨了 Objective-C 中的一些重要语法特性,包括 goto 语句、块(block)的使用、访问修饰符以及属性管理等。通过实例代码和详细解释,帮助开发者更好地理解和应用这些特性。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 使用GDI的一些AIP函数我们可以轻易的绘制出简 ... [详细]
  • 本文探讨了在Java多线程环境下,如何确保具有相同key值的线程能够互斥执行并按顺序输出结果。通过优化代码结构和使用线程安全的数据结构,我们解决了线程同步问题,并实现了预期的并发行为。 ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • ------------------------------————————————————————————————1.定义一个类,实现与被增强对象相同的接口2.在类中定义一个对象,记住被增强 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
author-avatar
谢丹逝梦
这个家伙很懒,什么也没留下!
Tags | 热门标签
RankList | 热门文章
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有