解析java.math.BigInteger类——构造函数
最早由于做作业,结识了java的BigInrger类。读着读着,越来越觉得有趣。后来作业做完,也不忍丢下它,索性把全部代码研究一遍。
开始的时候,一个上午时间最多读懂2个方法。但是还是有滋有味的坚持了下来。下面开始一点点剖开它“隐藏”的秘密。
首先要想搞懂两个问题:BigIngeter类的目的——实现高精度数的存储和计算。基础的实现机理——用int型(32位)数组存储数据。(在代码的注释中有详细说明)
/////////////////////////////////////////////////////////////
BigInteger类中的属性:{
int signum; 符号位,负数是为-1,零时为0,正数是为1
int[] mag; The magnitude of this BigInteger,大数的值
}
首先来分析下构造函数 (构造五部曲:1.检查是否符合标准 2.去零 3.mag赋值
4.去mag中零 5.符号位赋值)
1. 使用byte(8位)型数组构造BigInteger:
/////////////////////////////////////////////////////////////////////
public BigInteger(byte[] val) {
if (val.length == 0)
throw new NumberFormatException("Zero length BigInteger");
//传入数组长度为零,报错
if (val[0] < 0) {
mag = makePositive(val);
signum = -1;
//如果数组第一个值为负数,则将数组变正存入mag,signum赋-1
} else {
mag = stripLeadingZeroBytes(val);
//如果非负,则可直接去掉前面无效零,再赋给mag
signum = (mag.length == 0 ? 0 : 1);
}
}
下面看一下具体调用的函数
///////////////////////////////////////////////////////////////////////////
private static int[] stripLeadingZeroBytes(byte a[]) {
int byteLength = a.length;
int keep;
// Find first nonzero byte
for (keep=0; keep<a.length
&& a[keep]==0; keep++)
//找到第一个有效位,并用keep记录下
;
// Allocate new array and copy relevant part
of input array
int intLength = ((byteLength - keep) + 3)/4;
//计算int[]的长度,byte[1/2/3/4]对应int[1]
int[] result = new int[intLength];
int b = byteLength - 1;
for (int i = intLength-1; i >= 0; i--) {
result[i] = a[b--] & 0xff;
//向int[]赋值,&0xff的作用是消除对int前24位的影响
(计算机中使用补码存储数据,如果直接将一个第一位为“1”的byte值赋给int,则前24为将为“1”)
int bytesRemaining = b - keep + 1;
int bytesToTransfer = Math.min(3, bytesRemaining);
for (int j=8; j <= 8*bytesToTransfer; j += 8)
result[i] |= ((a[b--] & 0xff)
<< j);
//进行移位,每次移动8位,再进行或运算
}
return result;
}
//////////////////////////////////////////////////////////////
private static int[]
makePositive(byte a[]) {
int byteLength = a.length;
&& a[keep]==-1; keep++)
//找出非符号位(此处我看了很久才看懂)。若a[]=-1,即计算机中二进制为“11111111”,在int型中全为“1”的前几位被认为是符号位。要想转换成正的int值,只需要后几位即可。
&& a[k]==0; k++)
//由于传入参数数组第一个值必为负(由构造函数可得),所以不必考虑去零,变量k的作用只是判断需要“额外”位
//如果除符号位以外的全部为“0”,则需要“额外”1位来存储数据
int intLength = ((byteLength - keep + extraByte)
+ 3)/4;
int b = byteLength - 1;
for (int i = intLength-1; i >= 0;
i--) {
result[i]
= a[b--] & 0xff;
int
numBytesToTransfer = Math.min(3, b-keep+1);
if
(numBytesToTransfer < 0)
numBytesToTransfer = 0;
for (int
j=8; j <= 8*numBytesToTransfer; j += 8)
result[i] |= ((a[b--]
& 0xff) << j);
// Mask
indicates which bits must be complemented
int mask =
-1 >>>
(8*(3-numBytesToTransfer));
//将负值变为正值,即由原码转反码
result[i]
= ~result[i] & mask;
}
complement
result[i]
= (int)((result[i] & LONG_MASK) + 1);
//long LONG_MASK =
0xffffffffL;为了进行位运算而不考虑int符号问题
//(这个地方也把我蒙骗了好久)突然恍悟,其实就是+1后不为零,即不需要进位,就break退出吧!
break;
}
NumberFormatException("Zero length BigInteger");
mag =
makePositive(val);
trustedStripLeadingZeroInts(val);
? 0 : 1);
解析java.math.BigInteger类——构造函数的更多相关文章
- 算法笔记--java的BigInteger类及BigDecimal类
引包:import java.math.*; BigInteger类: 可以使用构造方法:public BigInteger(String val),或者valueOf(int)函数,如: BigIn ...
- 【java.math.BigInteger】【转】常见问题
好大的链接给原作 Q: 在java怎样将BigInteger类型的数据转成int类型的? A:BigInteger的intValue()可以获得int类型数值. Q: java.math.BigInt ...
- Java API —— BigInteger类
1.BigInteger类概述 可以让超过Integer范围内的数据进行运算 2.构造方法 public BigInteger(String val) 3.BigInteger类 ...
- java.math.BigInteger使用心得总结(转)
今天参考课本写了一个关于二进制与十进制转换的程序,程序算法不难,但写完后测试发现不论是二转十还是十转二,对于大于21亿即超过整数范围的数不能很好的转换.都会变成0.参考书籍发现使用使用BigInteg ...
- java.math.BigDecimal类
BigDecimal类用于高精度计算.一般的float型和Double型数据只可以用来做科学计算或者是工程计算,由于在商业计算中,要求的数字精度比较高,所以要用到java.math.BigDecima ...
- java基础-BigInteger类常用方法介绍
java基础-BigInteger类常用方法介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.BigInteger类概述 Java中long型为最大整数类型,对于超过long ...
- 连接Mysql时出现java.math.BigInteger cannot be cast to java.lang.Long问题
今天遇见这样一个坑.在连接数据库进行查询数据时,大家可能会遇见这样一个问题:java.math.BigInteger cannot be cast to java.lang.Long,然后去检查代码中 ...
- java.math.BigDecimal类multiply的使用
java.math.BigInteger.multiply(BigInteger val) 返回一个BigInteger,其值是 (this * val).声明 以下是java.math.BigInt ...
- 初学MyBatis(踩坑)Error querying database. Cause: java.sql.SQLException: java.lang.ClassCastException: java.math.BigInteger cannot be cast to java.lang.Long
最近在学习Mybatis,代码全部根据教程写好了,一运行结果报了一个错误,主要错误内容: Caused by: org.apache.ibatis.exceptions.PersistenceExce ...
随机推荐
- XML与DTD简介
(详细学习参考)https://blog.csdn.net/u013087513/article/details/52745509 XML约束之DTD的使用 (1)为什么要有约束? XML都是用户自定 ...
- c++ 的语法方面的问题
1.字符串string 中 ""和null的区别 答:举个例子,你老妈让你去打瓶酱油.你要是空手去了,你就是带着null去的.你要是带着空瓶子去的,你就是呆着“”去的.希望你能理 ...
- linux maven安装(三)
1.下载maven http://maven.apache.org/download.cgi 我下载的是:apache-maven-3.3.9-bin.tar.gz 解压:tar -zxvf apac ...
- Tomcat和JVM的性能调优总结
Tomcat性能调优: 找到Tomcat根目录下的conf目录,修改server.xml文件的内容.对于这部分的调优,我所了解到的就是无非设置一下Tomcat服务器的最大并发数和Tomcat初始化时创 ...
- bzoj 2961 共点圆 cdq+凸包+三分
题目大意 两种操作 1)插入一个过原点的圆 2)询问一个点是否在所有的圆中 分析 在圆中则在半径范围内 设圆心 \(x,y\) 查询点\(x_0,y_0\) 则\(\sqrt{(x-x_0)^2+(y ...
- c#.net分类上升达人~~~呵呵。。。
原文发布时间为:2008-11-11 -- 来源于本人的百度文章 [由搬家工具导入] 觉得自己蛮无聊的~~~~~~~~~(>_<)~~~~
- 2017 UESTC Training for Data Structures-解题报告
题目链接:http://acm.uestc.edu.cn/#/contest/show/155 这个数据结构训练主要针对线段树,树转数组和并查集.比较适合刚入门数据结构的同学. 注意,因为后面题的代码 ...
- springboot整合mybatis(SSM开发环境搭建)
0.项目结构: ---------------------方法一:使用mybatis官方提供的Spring Boot整合包实现--------------------- 1.application.p ...
- 什麼是 struct,union,enumeration 的 tag ?
struct tag { member-list }; union tag { member-list }; enum tag { member-list }; union test1 { int a ...
- AC日记——爱改名的小融 codevs 2967
2967 爱改名的小融 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 白银 Silver 题解 题目描述 Description Wikioi上有个人叫小融,他喜欢 ...