实现两个大整数的相加类的设计与实现

博客分类:
中兴的一道笔试题:如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算)。
package com.
import mons.lang.StringU
* @author jsczxy2
public class BigInt {
public static void main(String[] args) {
BigInt a = new BigInt("");
BigInt b = new BigInt("");
System.out.println(a.toString());
System.out.println(b.toString());
System.out.println(a.add(b));
private int[] arrayint = new int[100];
public BigInt(String num) {
//分解数字到int数组中
splitNumToArray(num);
public void splitNumToArray(String num) {
int j = 0;
StringBuffer sb = new StringBuffer();
//数字全部翻转后分组截取后再翻转回来加入int数组,这里控制数组中每一个int元素恒定为8位不超过int最大长度
num = new StringBuffer(num).reverse().toString();
for (int i = 0; i &num.length(); i++) {
if (i % 8 == 0) {
if (sb != null && !sb.toString().equals("")){
arrayint[j] = Integer.valueOf(sb.reverse().toString());
sb = new StringBuffer();
sb.append(num.charAt(i));
if (sb != null) {
arrayint[j] = Integer.valueOf(sb.reverse().toString());
//数组从后开始打印数字,不满8位补齐8位数字用0进行左填充
public String printArray(int[] array) {
StringBuffer sb = new StringBuffer();
boolean isNotFirstInt =
for (int i = array.length-1; i &=0 ; i--) {
if (array[i] != 0) {
System.out.println(i+":"+array[i]);
if(isNotFirstInt && String.valueOf(array[i]).length()&8){
sb.append(StringUtils.leftPad(String.valueOf(array[i]), 8,"0"));
sb.append(array[i]);
if(!isNotFirstInt)
isNotFirstInt =
return sb.toString();
//BigInt数字进行加法运算
public String add(BigInt bigInt) {
int[] a = this.
int[] b = bigInt.
int[] result = new int[100];
//根据各种情况进行结果赋值
for(int i=0;i&a.i++){
if(a[i]==0&&b[i]!=0){
result[i]=b[i];
}else if(a[i]!=0&&b[i]==0){
result[i]=a[i];
}else if(a[i]!=0&&b[i]!=0){
result[i]=a[i]+b[i];
result[i]=0;
//处理结果数组中超过8位的int元素的进位,该int元素截掉1位后再把其后一个元素值加一
for(int i=0;i&result.i++){
if(String.valueOf(result[i]).length()&8){
result[i] = Integer.valueOf(String.valueOf(result[i]).substring(1));
result[i+1] = result[i+1] + 1;
return printArray(result);
//打印BigInt数字
public String toString() {
return printArray(arrayint);
浏览: 737372 次
来自: 常州
我测试没啥区别啊!
renzhengzhi 写道drager 写道用jsoup后解 ...
感觉不对啊,通过实现Runnable接口来实现的线程里,使用T ...
下了一堆,不好使啊,求大神指点!超大整数类的C++实现_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
超大整数类的C++实现
&&超大整数类的C++实现,最大达1000位,效率较高。测试正确。
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩4页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢博客分类:
* 超大整数相加:
* 题目要求:如果系统要使用超大整数(超过long的范围),请你设计一个数据结构来存储这种
* 超大型数字以及设计一种算法来实现超大整数的加法运算
* @author Administrator
public class VeryBigNumAdd {
* @param args
public static void main(String[] args) {
// TODO Auto-generated method stub
String a="1223232";
for(int i=a.length()-1;i&=0;i--)
System.out.print(a.charAt(i));
VeryBigNumAdd vbn=new VeryBigNumAdd();
String a="634";
String b="634";
String result=vbn.doAdd(a,b);
System.out.println("result:"+result);
* @param a 加数字符串1
* @param b 加数字符串2
* @return 结果字符串
* 1、取得两个字符串的长度
* 2、把两个的长度做比较,并得出较长的长度,及较短的长度
* 3、把长度较短的加数字符串,在左面补0,使之与较长的字符串一样长
* 4、从最高位,一个个数的取出来相加,当然首先得转换为整型
* 5、设置进位,如果两个数相加及加上进位大于等于10,并且这不是最左边一个字符相加,相加结果等于
(取出1+取出2+进位)-10,并把进位设为1;如果没有大于10,就把进位设为0,如些循环,把
相加的结果以字符串的形式结合起来,就得到最后的结果
String doAdd(String a,String b)
String str="";
int lenA=a.length();
int lenB=b.length();
int maxLen=(lenA&lenB) ? lenA : lenB;
int minLen=(lenA&lenB) ? lenA : lenB;
String strTmp="";
for(int i=maxLen-minLi&0;i--)
strTmp+="0";
//把长度调整到相同
if(maxLen==lenA)
b=strTmp+b;
a=strTmp+a;
int JW=0;//进位
for(int i=maxLen-1;i&=0;i--)
int tempA=Integer.parseInt(String.valueOf(a.charAt(i)));
int tempB=Integer.parseInt(String.valueOf(b.charAt(i)));
if(tempA+tempB+JW&=10 && i!=0)
temp=tempA+tempB+JW-10;
temp=tempA+tempB+JW;
str=String.valueOf(temp)+
mygirl1314520
浏览: 70773 次
来自: 杭州
新手 学习了
[flash=200,200][url][img][list] ...
请问楼主,用post方法提交要是传2个参数应该怎么写?
受教了,多谢分享
将字符串信息转换为json格式,返回前台js中您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
基于大整数的BigDecimal类的实现.doc 18页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:200 &&
基于大整数的BigDecimal类的实现
你可能关注的文档:
··········
··········
基于大整数的BigDecimal类的实现
&P&基于大整数的BigDecimal类的实现&/P&
&P&  关键词:大数类;.NET;算法 &BR&摘要:以浮点运算的基本理论为基础,结合大整数类BigInteger的研究,采用面向对象技术,提出大数类BigDecimal的一种设计方法,并给出加、减、乘和除法的算法,最后给出C#语言程序实现。 &/P&
&P&&BR&  冯•络伊曼计算机,CPU的计算功能只能计算整数(integer,二进制),需要计算小数(decimal)的时候,就需要利用整数计算能力,通过一定的“方法”完成小数计算,这个“方法”就叫小数运算,它分为定点(fix)和浮点(float)运算两种。其中定点运算是将小数看成是由整数部分和小数部分m.n两个部分分别去计算,因非常浪费计算机资源,基本上不被采用。 &BR&  一、浮点数表示方法 &BR&  IEEE(电子电气工程师协会)在I985年制定的IEEE 754二进制浮点运算规范,是浮点运算事实上的工业标准,也是其它进制浮点运算的重要技术参考。 &BR&  计算机中的浮点运算,是小数点位置不固定,最大限度地扩大数值的表示范围,保持数值的有效精度,协调数值在表示范围和精度方面的要求,使计算机能够表示和运算较大的数字。为了满足小数点浮动的要求,任何一个数必须有两部分组成,一部分是阶码E,另一部分是尾数M,其中用阶数E表示小数点的位置,而尾数M表示一个数的有效数字。记为: &BR&  f=M×bE① &BR&  这种表示方法小数点不直观存在,并随E值浮动(浮点运算因此而得名)。 &BR&  如数f=.4,对于基b=10(十进制)情况下,可以表示成:0.4×1012,也可表示成4×10-13,而在b=109情况下[1],可以表示成:0.,也可表示成528 。 &BR&  文献[2]给出了十进制下的浮点数的另一种表示形式,这里将其扩展为任意基b(进制)的情况,即将①式以另一种形式表示: &BR&  f=M×bE=fn-1fn-2&#f-1⋯f-m=fn-1bn-1+ fn-2bn-2+⋯+f1b1+f0b0+f-1b-1+⋯+f-mb-m② &BR&  其中fi是一个b进制数字,可以有0,1,2,⋯⋯b-1任意数字,bi表示数码fi在数中的位置。如前面的f在基b=109时可表示为528b1++b-1+1234b-2. &BR&  ②式的两边同乘以因子bk可得到: &BR&  F=bkf=bk×M×bE=M×bE+k=fn-1bn+k-1+fn-2bn+k-2+⋯+f1b1+k+ f0b0+k+f-1bk-1+⋯+f-mbk-m(3) &BR&  此时每个数码左移k位(这里的“位”不能理解为就是十进制位,而应理解为b 进制下的位,如b=1
09时,一个位就是一个9位十进制数),相对的小数点右移k位。当k&=m 时小数点右移到数尾部,浮点数F就是一个整数了,此是有F=bkf,即f=Fb-k,即f变成尾数为纯整数的浮点数形式。利用浮点数的这个特点,可以将浮点运算转换成整数的运算。 &BR&  二、基于BigInteger的BigDecimal类及算法设计 &BR&  (一)基于BigInteger的BigDecimal类设计 &BR&  对于大的小数,即超出普通编程语言的浮点值集范围的数,都可以转化为一个大整数M乘bE的形式,所以自然就想到利用BigInteger类[3]构造一个新的大数类BigDecimal来解决大数浮点计算问题。 &BR&  从以上分析可以发现,在以b为基的浮点数域里,唯一决定一个大数的就是M和E。为了充分发挥BigInteger的作用,我们对①式进行规
正在加载中,请稍后...1495人阅读
在oj上做题时,相信大家遇到过很多要求大整数的题目,这时候,我们就需要用到所谓的高精度算法,即用数组来储存整数,模拟四则运算以及其他常见的运算,下面就让我们来分析一下几种实现大整数的方法
一.用vector来储存大整数
&span style=&font-size:24color:#FF0000;&&&strong&&span style=&font-size:14color:#000000;&&#include&iostream&
#include&vector&
#include&stack&
#include&cstring&
#include&string&
#include&cstdio&
class BigInteger
static const int base=;
static const int width=8;
vector&int&s;
BigInteger(long long num=0){*this=}
//构造函数
BigInteger operator=(long long num)
s.clear();
s.push_back(num%base);
}while(num&0);
BigInteger operator=(const string &str)
s.clear();
int x,len=(str.length()-1)/width+1;
for(int i=0;i&i++){
int end=str.length()-i*
int start=max(0,end-width);
sscanf(str.substr(start,end-start).c_str(),&%d&,&x);
//格式符%d是读入十进制整数
//string.c_str是Borland封装的String类中的一个函数,它返回当前字符串的首字符地址
s.push_back(x);
friend ostream & operator&&(ostream &out,const BigInteger& x)
//重载输出号
out&&x.s.back();
for(int i=x.s.size()-2;i&=0;i--){
char buf[20];
sprintf(buf,&%08d&,x.s[i]);
for(int j=0;j&int(strlen(buf));j++)
out&&buf[j];
friend istream & operator&&(istream &in,BigInteger& x)
//重载输入号
if(!(in&&s))
BigInteger operator+(const BigInteger& b)const
//重载加号
c.s.clear();
for(int i=0,g=0;;i++){
if(g==0&&i&=s.size()&&i&=b.s.size())
if(i&s.size()) x+=s[i];
if(i&b.s.size()) x+=b.s[i];
c.s.push_back(x%base);
BigInteger operator-(const BigInteger& b)
//重载减号,默认前面大于后面
c.s.clear();
if(*this&b){
for(i=0,g=0;;i++){
if(g==0&&i&=b.s.size())
if(s[i]&b.s[i]){
s[i+1]-=1;
s[i]=s[i]+
if(i&s.size()) x+=s[i];
if(i&b.s.size()) x-=b.s[i];
c.s.push_back(x%base);
for(;i&s.size();i++){
c.s.push_back(x%base);
bool operator&(const BigInteger& b)const
//重载小于号
if(s.size()!=b.s.size()) return s.size()&b.s.size();
for(int i=s.size()-1;i&=0;i--)
if(s[i]!=b.s[i]) return s[i]&b.s[i];
bool operator&(const BigInteger& b)const
//重载大于号
return b&*
bool operator&=(const BigInteger& b)const
return !(b&*this);
bool operator&=(const BigInteger& b)const
return !(*this&b);
bool operator==(const BigInteger& b)const
//重载等于号
return !(b&*this)&&!(*this&b);
BigInteger operator+=(const BigInteger& b)
*this=(*this+b);
BigInteger operator-=(const BigInteger& b)
*this=(*this-b);
};&/span&&/strong&&/span&
这段代码是我参照算法竞赛入门上面的,下面我们来分析一下具体实现过程:
&&&&&& 首先定义了base=,width=8,来实现大整数每8位用int的方式保存进vector内,然后通过重载赋值运算符,输入字符串的形式实现将字符串转换为vector容器值。
&&&&&& 然后是加法的重载实现,通过每取八位出来进行+运算,若结果大于8位则进一位,并将这一位保留到下一次的运算中。
&&&&&& 而减法的重载实现,则是通过每取八位出来进行-运算,若结果小于0则从s[i+1],也就是vector容器内后一个值中取出来进行计算,而s[i+1]则减一来实现借位。
二.通过数组的方式储存大整数
&span style=&font-size:24color:#FF0000;&&&strong&&span style=&color:#000000;&&&span style=&font-size:14&&#include&string&
#include&iostream&
#include&iosfwd&
#include&cmath&
#include&cstring&
#include&stdlib.h&
#include&stdio.h&
#include&cstring&
#define MAX_L 2005
class bign
int len, s[MAX_L];//数的长度,记录数组
//构造函数
bign(const char*);
bign(int);
//符号 1正数 0负数
string toStr()//转化为字符串,主要是便于输出
friend istream& operator&&(istream &,bign &);//重载输入流
friend ostream& operator&&(ostream &,bign &);//重载输出流
//重载复制
bign operator=(const char*);
bign operator=(int);
bign operator=(const string);
//重载各种比较
bool operator&(const bign &)
bool operator&=(const bign &)
bool operator&(const bign &)
bool operator&=(const bign &)
bool operator==(const bign &)
bool operator!=(const bign &)
//重载四则运算
bign operator+(const bign &)
bign operator++();
bign operator++(int);
bign operator+=(const bign&);
bign operator-(const bign &)
bign operator--();
bign operator--(int);
bign operator-=(const bign&);
bign operator*(const bign &)
bign operator*(const int num)
bign operator*=(const bign&);
bign operator/(const bign&)
bign operator/=(const bign&);
//四则运算的衍生运算
bign operator%(const bign&)//取模(余数)
bign factorial()//阶乘
bign Sqrt()//整数开根(向下取整)
bign pow(const bign&)//次方
//辅助的函数
void clean();
#define max(a,b) a&b ? a : b
#define min(a,b) a&b ? a : b
bign::bign()
memset(s, 0, sizeof(s));
bign::bign(const char *num)
bign::bign(int num)
string bign::toStr() const
for (int i = 0; i & i++)
res = (char)(s[i] + '0') +
if (res == &&)
res = &0&;
if (!sign&&res != &0&)
res = &-& +
istream &operator&&(istream &in, bign &num)
ostream &operator&&(ostream &out, bign &num)
out&&num.toStr();
bign bign::operator=(const char *num)
memset(s, 0, sizeof(s));
char a[MAX_L] = &&;
if (num[0] != '-')
strcpy(a, num);
for (int i = 1; i & strlen(num); i++)
a[i - 1] = num[i];
sign = !(num[0] == '-');
len = strlen(a);
for (int i = 0; i & strlen(a); i++)
s[i] = a[len - i - 1] - 48;
bign bign::operator=(int num)
if (num & 0)
sign = 0, num = -
char temp[MAX_L];
sprintf(temp, &%d&, num);
bign bign::operator=(const string num)
const char *
tmp = num.c_str();
bool bign::operator&(const bign &num) const
if (sign^num.sign)
return num.
if (len != num.len)
return len & num.
for (int i = len - 1; i &= 0; i--)
if (s[i] != num.s[i])
return sign ? (s[i] & num.s[i]) : (!(s[i] & num.s[i]));
bool bign::operator&(const bign&num)const
return num & *
bool bign::operator&=(const bign&num)const
return !(*this&num);
bool bign::operator&=(const bign&num)const
return !(*this&num);
bool bign::operator!=(const bign&num)const
return *this & num || *this &
bool bign::operator==(const bign&num)const
return !(num != *this);
bign bign::operator+(const bign &num) const
if (sign^num.sign)
bign tmp = sign ? num : *
tmp.sign = 1;
return sign ? *this - tmp : num -
result.len = 0;
int temp = 0;
for (int i = 0; temp || i & (max(len, num.len)); i++)
int t = s[i] + num.s[i] +
result.s[result.len++] = t % 10;
temp = t / 10;
result.sign =
bign bign::operator++()
*this = *this + 1;
bign bign::operator++(int)
bign old = *
++(*this);
bign bign::operator+=(const bign &num)
*this = *this +
bign bign::operator-(const bign &num) const
bign b=num,a=*
if (!num.sign && !sign)
return b-a;
if (!b.sign)
return a+b;
if (!a.sign)
b=bign(0)-(a+b);
bign c=(b-a);
result.len = 0;
for (int i = 0, g = 0; i & a. i++)
int x = a.s[i] -
if (i & b.len) x -= b.s[i];
if (x &= 0) g = 0;
result.s[result.len++] =
result.clean();
bign bign::operator * (const bign &num)const
result.len = len + num.
for (int i = 0; i & i++)
for (int j = 0; j & num. j++)
result.s[i + j] += s[i] * num.s[j];
for (int i = 0; i & result. i++)
result.s[i + 1] += result.s[i] / 10;
result.s[i] %= 10;
result.clean();
result.sign = !(sign^num.sign);
bign bign::operator*(const int num)const
bign z = *
return x*z;
bign bign::operator*=(const bign&num)
*this = *this *
bign bign::operator /(const bign&num)const
ans.len = len - num.len + 1;
if (ans.len & 0)
ans.len = 1;
bign divisor = *this, divid =
divisor.sign = divid.sign = 1;
int k = ans.len - 1;
int j = len - 1;
while (k &= 0)
while (divisor.s[j] == 0) j--;
if (k & j) k =
char z[MAX_L];
memset(z, 0, sizeof(z));
for (int i = i &= i--)
z[j - i] = divisor.s[i] + '0';
bign dividend =
if (dividend & divid) { k--; }
int key = 0;
while (divid*key &= dividend) key++;
ans.s[k] =
bign temp = divid*
for (int i = 0; i & i++)
temp = temp * 10;
divisor = divisor -
ans.clean();
ans.sign = !(sign^num.sign);
bign bign::operator/=(const bign&num)
*this = *this /
bign bign::operator%(const bign& num)const
bign a = *this, b =
a.sign = b.sign = 1;
bign result, temp = a / b*b;
result = a -
result.sign =
bign bign::pow(const bign& num)const
bign result = 1;
for (bign i = 0; i & i++)
result = result*(*this);
bign bign::factorial()const
bign result = 1;
for (bign i = 1; i &= * i++)
void bign::clean()
if (len == 0) len++;
while (len & 1 && s[len - 1] == '\0')
bign bign::Sqrt()const
if(*this&0)return -1;
if(*this&=1)return *
bign l=0,r=*this,
while(r-l&1)
mid=(l+r)/2;
if(mid*mid&*this)
bign::~bign()
}&/span&&/span&&/strong&&/span&
这是通过数组来储存大整数,数组的每一个空间储存一个数字,来达到保存大整数的目的。
大整数加减法的实现跟前面的基本一样,也是通过模拟进位,借位的方法来实现。
下面来说一下乘法的实现过程,乘法的实现,是通过模拟手算的方法,第一个数的每一位,乘以第二个数的每一位,最后通过汇总,把结果算出来。
而除法则是四则运算中最复杂的一个,基本思路是一个一个减,看最多能减去多少个除数,但显然这样做的话效率简直是极其得低。如何使它减得更快呢?以 7546 除以 23 为例来看一下:开始商为 0。先减
去 23 的 100 倍,就是 2300,发现够减 3 次,余下 646。于是商的值就增加 300。然后用 646
减去 230,发现够减 2 次,余下 186,于是商的值增加 20。最后用 186 减去 23,够减 8 次,
因此最终商就是 328。
而上面正是用到了这种思路。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4694次
排名:千里之外
(2)(1)(1)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'

我要回帖

更多关于 c语言如何实现大整数 的文章

 

随机推荐