IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 躲不掉的java高精度计算 -> 正文阅读

[Java知识库]躲不掉的java高精度计算

为什么用高精度?

举个栗子,如果用Java语言写个程序来计算138651223773355+786437100。

使用int类型肯定不行,因为int的范围是-2147483648 到2147483647之间。使用long类型可以解决这个问题,但是如果要求138651223773355*786437100的值呢?long类型也是不够用的,long的范围是-9223372036854775808到+9223372036854775807之间,所以我们需要一个范围足够大的类型来计算。

java提供的高精度类型

  • 高精度整数BigInteger
  • 高精度浮点数BigDecimal

API中的描述BigInteger

不可变的任意精度整数。所有操作的行为就好像大整数是用二进制补码表示的(就像Java的基本整数类型一样)。BigInteger提供了Java所有原始整数运算符的类似物,以及java.lang.Math的所有相关方法。此外,BigInteger还提供了模块化算术、GCD计算、素性测试、素生成、位操作和一些其他杂项操作的操作。
算术运算的语义完全模仿了Java语言规范中定义的整数算术运算符的语义。例如,除以零会引发算术异常,将负数除以正数会产生负数(或零)余数。规范中关于溢出的所有细节都被忽略了,因为大整数被做得足够大以适应操作的结果。

移位操作的语义扩展了Java的移位操作符的语义,允许负的移位距离。具有负偏移距离的右偏移导致左偏移,反之亦然。省略了无符号右移运算符(> >),因为该操作与该类提供的“无限字长”抽象相结合没有什么意义。

按位逻辑运算的语义完全模仿了Java的按位整数运算符。二进制运算符(and、or、xor)在执行运算之前会隐式地对两个操作数中较短的一个执行符号扩展。

比较操作执行有符号整数比较,类似于Java的关系运算符和等式运算符。

提供模算术运算来计算余数、执行幂运算和计算乘法逆。这些方法总是返回一个介于0和(modulus)之间的非负结果。

位操作对其操作数的二进制补码表示的单个位进行操作。如有必要,操作数会进行符号扩展,以便包含指定的位。没有一个单比特操作可以产生一个符号与正在操作的大整数不同的大整数,因为它们只影响一个比特,并且这个类提供的“无限字长”抽象确保了每个大整数前面有无限多的“虚拟符号比特”。

为了简洁明了,在对BigInteger方法的描述中使用了伪代码。伪代码表达式(i + j)是“一个BigInteger,它的值是BigInteger i的值加上BigInteger j的值”的简写形式。伪代码表达式(i == j)是“当且仅当BigInteger i表示与BigInteger j相同的值时为真”的简写形式。其他伪代码表达式的解释类似。

当传递任何输入参数的空对象引用时,此类中的所有方法和构造函数都会引发NullPointerException。

API中的描述BigDecimal

不可变的任意精度带符号十进制数。BigDecimal由一个任意精度的整数小数位数和一个32位整数小数位数组成。如果为零或正,刻度是小数点右边的位数。如果为负,则该数字的未缩放值乘以10的比例的负幂。因此,用大十进制表示的数值是(无标度值× 10标度)。
BigDecimal类提供算术、比例操作、舍入、比较、散列和格式转换等操作。toString()方法提供了BigDecimal的规范表示。

BigDecimal类让用户可以完全控制舍入行为。如果未指定舍入模式,并且无法表示确切的结果,则会引发异常;否则,可以通过向操作提供适当的MathContext对象,按照选定的精度和舍入模式进行计算。在任一种情况下,都提供了八种舍入模式来控制舍入。用这个类中的整数字段(如ROUND_HALF_UP)来表示舍入模式,在很大程度上已经过时;RoundingMode枚举的枚举值(如RoundingMode。应该改为使用HALF_UP)。

当数学上下文对象的精度设置为0时(例如,数学上下文。无限制),算术运算是精确的,就像没有MathContext对象的算术方法一样。(这是5之前版本中支持的唯一行为。)作为计算精确结果的必然结果,不使用精度设置为0的MathContext对象的舍入模式设置,因此不相关。在除法的情况下,精确的商可以有无限长的十进制展开;例如,1除以3。如果商具有非终止的十进制扩展,并且指定该操作返回精确的结果,则会引发算术异常。否则,将返回除法的确切结果,就像对其他操作所做的那样。

当精度设置不为0时,BigDecimal算法的规则与ANSI X3.274-1996和ANSI X3.274-1996/AM 1-2000(第7.4节)中定义的算法的选定操作模式大致兼容。与这些标准不同,BigDecimal包含许多舍入模式,在5之前的BigDecimal版本中,舍入模式是除法的必备条件。这些ANSI标准和BigDecimal规范之间的任何冲突都将通过支持BigDecimal来解决。

由于相同的数值可以有不同的表示(不同的比例),算术和舍入规则必须指定数值结果和结果表示中使用的比例。

通常,舍入模式和精度设置决定了当精确结果的位数(在除法的情况下可能无限多)多于返回的位数时,运算如何返回有限位数的结果。首先,返回的总位数由MathContext的精度设置指定;这决定了结果的精度。数字计数从精确结果最左边的非零数字开始。舍入模式决定了任何丢弃的尾随数字如何影响返回的结果。

对于所有算术运算符,执行运算时就像首先计算精确的中间结果,然后使用选定的舍入模式舍入到精度设置指定的位数(如有必要)。如果没有返回确切的结果,则丢弃确切结果的一些数字位置。当舍入增加返回结果的幅度时,进位传播到前面的“9”位就有可能创建一个新的数字位置。例如,将值999.9舍入到三位数,舍入后的数字等于一千,表示为100×101。在这种情况下,新的“1”是返回结果的前导数字位置。

提供的方法

BigInteger和BigDecimal有相同的方法。

1.常用方法:

  • 加:a.add(b);
  • 减:a.subtract(b);
  • 乘:a.multiply(b);
  • 除:a.divide(b);
  • 次方:a.pow(n),其中n为int类型的数;
  • 取绝对值:a.abs();

在这里还是要说一下除法

BigDecimal.divide(BigDecimal?divisor, int?scale,?RoundingMode?roundingMode)?;

如:

        BigDecimal b1 = new BigDecimal("123.564");
        BigDecimal b2 = new BigDecimal("3.3");
        BigDecimal divide = b1.divide(b2, 10, RoundingMode.HALF_UP);

?10表示的是精确到小数点后几位

ROUND_CEILING:舍位时往正无穷方向移动? ?
正数:1.1 -> 2?? 1.5-> 2?? 1.8-> 2? ?
负数:-1.1-> -1?? -1.5-> -1?? -1.8-> -1
ROUND_DOWN:向0的方向移动
正数:1.1-> 1?? 1.5-> 1?? 1.8-> 1? ?
负数:-1.1-> -1?? -1.5-> -1?? -1.8> -1
ROUND_FLOOR:与CEILING相反,往负无穷? ?
正数: 1.1-> 1?? 1.5-> 1?? 1.8-> 1? ?
负数: -1.1-> -2?? -1.5-> -2?? -1.8-> -2
ROUND_HALF_DOWN:以5为分界线,或曰五舍六入
正数:1.5-> 1?? 1.6-> 2 ?
负数:-1.5-> -1?? -1.6-> -2??
ROUND_HALF_EVEN:同样以5为分界线,如果是5,则前一位变偶数
1.15-> 1.2?? 1.16-> 1.2?? 1.25-> 1.2?? 1.26-> 1.3
ROUND_HALF_UP:最常见的四舍五入
ROUND_UNNECESSARY:无需舍位
ROUND_UP与ROUND_DOWN相反,远离0的方向
正数:1.1-> 2?? 1.5-> 2?? 1.8-> 2
负数:-1.1-> -2?? -1.5-> -2?? -1.8-> -2

2.其他方法:

  • 取反:a.negate();
  • 设置精确到小数点后几位:a.setScale();
  • 比较大小:a.compareTo(b),大于为1,小于为-1,等于为0;
  • 取模:a.remainder(b),与“%”,相似但不同。
  • 转化为字符串:a.toString()

拿例题说话

输入两行分别表示两个正整数a,b,求出a除以b的商以及余数。
a的长度不超过1000,b不超过int范围。

输出格式:

输出两行分别表示商和余数

?输入样例:

1388234123
66666

输出样例:

20823
48005

?完整代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.RoundingMode;

public class p1091 {
    public static void main(String[] args) {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        //BufferedReader类从字符输入流中读取文本并缓冲字符,以便有效地读取字符,数组和行
        //可以通过构造函数指定缓冲区大小也可以使用默认大小。对于大多数用途,默认值足够大
        //BufferedReader的读取速度是比Scanner更快的
        try {
            String num1=br.readLine();//读取输入内容
            String num2=br.readLine();
            BigDecimal bd1=new BigDecimal(num1);//这里用的是浮点数
            BigDecimal bd2=new BigDecimal(num2);
            BigDecimal bd3= bd1.divide(bd2,0, RoundingMode.DOWN);//获取商
            System.out.println(bd3);
            System.out.println(bd1.subtract(bd3.multiply(bd2)));//获取余数
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-01-16 12:54:46  更:2022-01-16 12:55:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:42:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码