热门标签 | 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可以指定好四舍五入的精确位置。


推荐阅读
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 深入理解Java中的volatile、内存屏障与CPU指令
    本文详细探讨了Java中volatile关键字的作用机制,以及其与内存屏障和CPU指令之间的关系。通过具体示例和专业解析,帮助读者更好地理解多线程编程中的同步问题。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • c# – UWP:BrightnessOverride StartOverride逻辑 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
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社区 版权所有