转:

(原出处不可考,若有侵权,请联系我立即删除)

头文件:

// WTNumber.h: interface for the CWTNumber class.
//
////////////////////////////////////////////////////////////////////// #if !defined(AFX_WTNUMBER_H__92E62B40_491A_4A75_AB89_FFB160DB2343__INCLUDED_)
#define AFX_WTNUMBER_H__92E62B40_491A_4A75_AB89_FFB160DB2343__INCLUDED_ #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000 #define INT_BIT_MAX 255
#define FLOAT_BIT_MAX 255 class CWTNumber
{
private:
int intbits; /* 整数数位*/
int floatbits; /* 小数有效数位*/
char infinite; /* 无穷大*/
char sign; /* 符号*/
char intpart[INT_BIT_MAX]; /* 整数部分*/
char floatpart[FLOAT_BIT_MAX]; /* 小数部分*/
private:
char* m_sz;
public:
/* 算术函数指针类型.*/
typedef void (*PFNCALC)(const CWTNumber&,const CWTNumber&,CWTNumber&);
CWTNumber();
CWTNumber(const char* szNum);
~CWTNumber();
/* 转换成字符串*/
char* ToString();
void FreeString();
/* 初始化WTNumber为0.*/
void InitWTNumberToZero();
/* 判断需要多少个字符空间存储WTNumber转换的字符串.*/
int StrLenByWTNumber();
/* 从字符串转换到WTNumber.*/
void StrToWTNumber(const char *arr);
/* 从WTNumber转换到字符串.*/
void WTNumberToStr(char *szBuf);
/* 调节数位,删除最高整数位是0的和最低小数位是0的数位.*/
void AdjustBits();
/* 移动小数点,delta=0不移动,delta<0往左移动,delta>0往右移动.*/
void MoveFloatPoint(int delta);
/* 使无穷大 */
void MakeInfinite();
/* 比较2个数大小 */
int WTCompare(const CWTNumber& n) const;
/* 判断是否为0 */
int IsZero() const;
/* 赋值号重载*/
CWTNumber& operator=(const CWTNumber& n); /* 运算符重载 */
CWTNumber operator+(const CWTNumber& n);
CWTNumber operator-(const CWTNumber& n);
CWTNumber operator*(const CWTNumber& n);
CWTNumber operator/(const CWTNumber& n);
CWTNumber& operator+=(const CWTNumber& n);
CWTNumber& operator-=(const CWTNumber& n);
CWTNumber& operator*=(const CWTNumber& n);
CWTNumber& operator/=(const CWTNumber& n); bool operator>(const CWTNumber& n);
bool operator>=(const CWTNumber& n);
bool operator<(const CWTNumber& n);
bool operator<=(const CWTNumber& n);
bool operator==(const CWTNumber& n);
bool operator!=(const CWTNumber& n);
/* 加法*/
static void WTAdd(const CWTNumber& n1,const CWTNumber& n2,CWTNumber& Res);
/* 乘法*/
static void WTMultiply(const CWTNumber& n1,const CWTNumber& n2,CWTNumber& Res);
/* 减法*/
static void WTSubtract(const CWTNumber& n1,const CWTNumber& n2,CWTNumber& Res);
/* 除法*/
static void WTDivide(const CWTNumber& n1,const CWTNumber& n2,CWTNumber& Res);
/* 根据算术函数返回结果 */
static char *Result(const char *val1,const char *val2,PFNCALC pfnCalc);
}; #endif // !defined(AFX_WTNUMBER_H__92E62B40_491A_4A75_AB89_FFB160DB2343__INCLUDED_)

源文件:

// WTNumber.cpp: implementation of the CWTNumber class.
//
//////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdlib.h>
#include "WTNumber.h" //////////////////////////////////////////////////////////////////////
// Construction/Destruction
////////////////////////////////////////////////////////////////////// CWTNumber::CWTNumber()
{
InitWTNumberToZero();
}
CWTNumber::CWTNumber(const char* szNum)
{
InitWTNumberToZero();
StrToWTNumber(szNum);
}
CWTNumber::~CWTNumber()
{
FreeString();
}
void CWTNumber::FreeString()
{
if(m_sz) delete []m_sz;
m_sz=NULL;
}
void CWTNumber::InitWTNumberToZero()
{
memset(this,,sizeof(CWTNumber));
}
int CWTNumber::StrLenByWTNumber()
{
int len = floatbits+intbits+;
if(intbits==) len++; /* .1 --> 0.1*/
if(floatbits) len++; /* '.'*/
if(sign) len++; /* '-'*/
if(infinite) return ; /* #INFINITE */
return len;
}
void CWTNumber::StrToWTNumber(const char *arr)
{
char *point;
InitWTNumberToZero();
if(*arr=='-') /* 如果是负数*/
{
arr++;
sign=;
}
point=strchr(arr,'.');
if(point) /* 找到小数点 */
{
int n=intbits=point-arr; /* 计算出整数数位 */
while(n) /* 整数数位不==0则循环 */
{
intpart[intbits-n]=arr[n-]-''; /* 将数字低位存在低下标元素*/
n--;
}
while(*++point)
{
floatpart[floatbits]=*point-'';
floatbits++;
}
}
else /* 说明没写小数点,全是整数.*/
{
int n=intbits=strlen(arr);
while(n)
{
intpart[intbits-n]=arr[n-]-'';
n--;
}
}
AdjustBits();
/* 处理-0 和0的情况*/
if(floatbits==)
{
if(intbits== || intbits==&&intpart[]==)
sign=;
}
} void CWTNumber::WTNumberToStr(char *szBuf)
{
int n=intbits,c;
memset(szBuf,,StrLenByWTNumber());
if(sign) /* 如果是负数*/
{
*szBuf++='-';
}
if(infinite)
{
strcat(szBuf,"#INFINITE");
return;
}
while(n)
{
szBuf[intbits-n]=intpart[n-]+'';
n--;
}
c=; /* 是否加了0*/
if(intbits==) {
strcat(szBuf,"");
c=;
}
if(floatbits) strcat(szBuf,".");
n=;
while(n<floatbits)
{
szBuf[intbits++n+c]=floatpart[n]+'';
n++;
}
}
void CWTNumber::AdjustBits()
{
while(intbits>&&intpart[intbits-]==) intbits--;
while(floatbits&&floatpart[floatbits-]==) floatbits--;
}
void CWTNumber::MoveFloatPoint(int delta)
{
/* delta<0则往左移动小数点,delta>0则向右移动小数点 */
if(delta)
{
CWTNumber n=*this;
InitWTNumberToZero();
sign=n.sign;
if(delta<)
{
int i;
delta=-delta;
for(i=delta;i<n.intbits;i++)
{
intpart[intbits++]=n.intpart[i];
}
for(i=delta-;i>=;i--)
{
floatpart[floatbits++]=n.intpart[i];
}
for(i=;i<n.floatbits;i++)
{
floatpart[floatbits++]=n.floatpart[i];
}
}
else
{
int i;
for(i=delta;i<n.floatbits;i++) /* 处理小数部分*/
{
floatpart[floatbits++]=n.floatpart[i];
}
for(i=delta-;i>=;i--) /* 小数到整数的部分*/
{
intpart[intbits++]=n.floatpart[i];
}
for(i=;i<n.intbits;i++) /* 整数部分*/
{
intpart[intbits++]=n.intpart[i];
}
}
}
AdjustBits();
}
void CWTNumber::MakeInfinite()
{
infinite=;
} int CWTNumber::WTCompare(const CWTNumber& n) const
{
/* 首先是比较符号*/
if(sign==&&n.sign!=) /* pn1是正数,pn2是负数*/
return ; /* >*/
else if(sign!=&&n.sign==) /* pn1是负数,pn2是正数*/
return -; /* <*/
else /* 同号状态*/
{
/* 比较整数部分*/
if(intbits>n.intbits) /* pn1整数数位多*/
return sign?-:;
else if(intbits<n.intbits)
return sign?:-;
else /* 整数数位相同*/
{
int i=intbits-; /*指到最高位*/
while(i>=)
{
if(intpart[i]>n.intpart[i])
return sign?-:;
else if(intpart[i]<n.intpart[i])
return sign?:-;
else i--;
}
/* 整数部分相同,比较小数部分*/
for(i=;i<floatbits&&i<n.floatbits;)
{
if(floatpart[i]>n.floatpart[i])
return sign?-:;
else if(floatpart[i]<n.floatpart[i])
return sign?:-;
else i++;
}
if(i<floatbits) return sign?-:;
if(i<n.floatbits) return sign?:-;
return ; /* 相等*/
}
}
}
int CWTNumber::IsZero() const
{
if(floatbits==&&intbits==) return ;
if(floatbits==&&intbits==&&intpart[]==) return ;
return ;
} void CWTNumber::WTAdd(const CWTNumber& n1,const CWTNumber& n2,CWTNumber& Res)
{
Res.InitWTNumberToZero();
if(n1.sign^n2.sign) /*异号*/
{
CWTNumber rn2=n2;
rn2.sign=n1.sign;
WTSubtract(n1,rn2,Res);
}
else /*同号*/
{
int maxfloatbits=n1.floatbits>n2.floatbits?n1.floatbits:n2.floatbits;
int addbit=; /* 进位值*/
int i,j;
for(i=maxfloatbits-;i>=;i--)
{
int value=n1.floatpart[i]+n2.floatpart[i]+addbit;
addbit=value/; /* 看看是否超过10. 设置进位值*/
Res.floatpart[i]=value%;
}
Res.floatbits=maxfloatbits;
/* 到此,小数部分计算完毕.*/
for(j=;j<n1.intbits||j<n2.intbits;j++)
{
int value=n1.intpart[j]+n2.intpart[j]+addbit;
addbit=value/;
Res.intpart[j]=value%;
Res.intbits++;
}
if(addbit>)
{
Res.intpart[j]=addbit;
Res.intbits++;
}
Res.sign=n1.sign; /*决定符号*/
Res.AdjustBits();
}
} void CWTNumber::WTMultiply(const CWTNumber& n1,const CWTNumber& n2,CWTNumber& Res)
{
CWTNumber z1=n1,z2=n2;
CWTNumber sum;
int i,j;
sum.InitWTNumberToZero();
Res.InitWTNumberToZero();
z1.MoveFloatPoint(z1.floatbits);
z2.MoveFloatPoint(z2.floatbits);
/* 计算z1*z2 */
for(i=;i<z2.intbits;i++)
{
CWTNumber tmp; /* 存放临时乘积*/
int addbit=;
tmp.intbits=z1.intbits+i;
for(j=;j<z1.intbits;j++)
{
int value = z2.intpart[i]*z1.intpart[j]+addbit;
addbit=value/;
tmp.intpart[j+i]=value%;
}
if(addbit)
{
tmp.intpart[j+i]=addbit;
tmp.intbits++;
}
WTAdd(sum,tmp,Res);
sum=Res;
}
Res=sum;
Res.MoveFloatPoint(-(n1.floatbits+n2.floatbits));
/* 判断符号,异号为负*/
if(n1.sign^n2.sign) Res.sign=;
} void CWTNumber::WTSubtract(const CWTNumber& n1,const CWTNumber& n2,CWTNumber& Res)
{
Res.InitWTNumberToZero();
if(n1.sign^n2.sign) /* 异号情况*/
{
CWTNumber rn2=n2;
rn2.sign=n1.sign;
WTAdd(n1,rn2,Res);
}
else /* 同号情况*/
{
int cmp=n1.WTCompare(n2);
int swapflag,i,maxfloatbits,subtractbit;
if(cmp==) return; /* 相等就没必要再减了.*/
swapflag=n1.sign==?cmp==-:cmp==;
const CWTNumber* pn1=&n1;
const CWTNumber* pn2=&n2;
if(swapflag)
{
const CWTNumber *t=pn1;
pn1=pn2;
pn2=t;
}
maxfloatbits=pn1->floatbits>pn2->floatbits?pn1->floatbits:pn2->floatbits;
subtractbit=; /* 退位值*/
/* 先计算小数部分*/
for(i=maxfloatbits-;i>=;i--)
{
if(pn1->floatpart[i]-subtractbit<pn2->floatpart[i])
{
int value=pn1->floatpart[i]-pn2->floatpart[i]-subtractbit+;
subtractbit=;
Res.floatpart[i]=value;
}
else
{
int value=pn1->floatpart[i]-pn2->floatpart[i]-subtractbit;
subtractbit=;
Res.floatpart[i]=value;
}
}
Res.floatbits=maxfloatbits;
/* 至此小数部分计算完毕.*/
for(i=;i<pn1->intbits||i<pn2->intbits;i++)
{
if(pn1->intpart[i]-subtractbit<pn2->intpart[i])
{
int value=pn1->intpart[i]-pn2->intpart[i]-subtractbit+;
subtractbit=;
Res.intpart[i]=value;
}
else
{
int value=pn1->intpart[i]-pn2->intpart[i]-subtractbit;
subtractbit=;
Res.intpart[i]=value;
}
Res.intbits++;
}
Res.sign=swapflag?!n1.sign:n1.sign; /*决定符号*/
Res.AdjustBits();
}
}
void CWTNumber::WTDivide(const CWTNumber& n1,const CWTNumber& n2,CWTNumber& Res)
{
CWTNumber z1=n1,z2=n2;
int deta=z2.floatbits-z1.floatbits;
z1.MoveFloatPoint(z1.floatbits);
z2.MoveFloatPoint(z2.floatbits);
Res.InitWTNumberToZero();
if(n1.IsZero()) return ;
if(n2.IsZero()) {
Res.sign=n1.sign;
Res.MakeInfinite();
return ;
}
z1.sign=z2.sign=; /*统一符号,便于比较大小*/
while(z1.intbits!=z2.intbits) { /*确保数位相等,这步耗费很多时间*/
if(z1.intbits<z2.intbits) {
z1.MoveFloatPoint();
deta--;
} else {
z2.MoveFloatPoint();
deta++;
}
}
while(Res.floatbits<(INT_BIT_MAX/)) {
int cmp=z1.WTCompare(z2);
int n=;
CWTNumber mulres,subres;
if(cmp==-) { /*z1<z2*/
z1.MoveFloatPoint();
Res.floatpart[Res.floatbits++]=;
continue;
} else if(cmp==) { /*z1==z2*/
Res.floatpart[Res.floatbits++]=;
break;
}
do { /*找商*/
CWTNumber tmp;
tmp.intpart[]=--n;
tmp.intbits=;
WTMultiply(z2,tmp,mulres);
} while((cmp=mulres.WTCompare(z1))==);
Res.floatpart[Res.floatbits++]=n;
if(cmp==) break;
WTSubtract(z1,mulres,subres);
subres.MoveFloatPoint();
z1=subres;
}
Res.MoveFloatPoint();
Res.MoveFloatPoint(deta);
/* 判断符号,异号为负*/
if(n1.sign^n2.sign) Res.sign=;
}
char *CWTNumber::Result(const char *val1,const char *val2,PFNCALC pfnCalc)
{
CWTNumber n1,n2,res;
n1.StrToWTNumber(val1);
n2.StrToWTNumber(val2);
pfnCalc(n1,n2,res);
return res.ToString();
} char* CWTNumber::ToString()
{
FreeString();
m_sz=new char[StrLenByWTNumber()];
WTNumberToStr(m_sz);
return m_sz;
} CWTNumber& CWTNumber::operator=(const CWTNumber& n)
{
if(this!=&n) {
FreeString();
memcpy(this,&n,sizeof(CWTNumber));
if(n.m_sz)
{
m_sz=strdup(n.m_sz);
}
}
return *this;
} CWTNumber CWTNumber::operator+(const CWTNumber& n)
{
CWTNumber res;
CWTNumber::WTAdd(*this,n,res);
return res;
}
CWTNumber CWTNumber::operator-(const CWTNumber& n)
{
CWTNumber res;
CWTNumber::WTSubtract(*this,n,res);
return res;
}
CWTNumber CWTNumber::operator*(const CWTNumber& n)
{
CWTNumber res;
CWTNumber::WTMultiply(*this,n,res);
return res;
}
CWTNumber CWTNumber::operator/(const CWTNumber& n)
{
CWTNumber res;
CWTNumber::WTDivide(*this,n,res);
return res;
}
CWTNumber& CWTNumber::operator+=(const CWTNumber& n)
{
CWTNumber n1=*this,n2=n;
CWTNumber::WTAdd(n1,n2,*this);
return *this;
}
CWTNumber& CWTNumber::operator-=(const CWTNumber& n)
{
CWTNumber n1=*this,n2=n;
CWTNumber::WTSubtract(n1,n2,*this);
return *this;
}
CWTNumber& CWTNumber::operator*=(const CWTNumber& n)
{
CWTNumber n1=*this,n2=n;
CWTNumber::WTMultiply(n1,n2,*this);
return *this;
}
CWTNumber& CWTNumber::operator/=(const CWTNumber& n)
{
CWTNumber n1=*this,n2=n;
CWTNumber::WTDivide(n1,n2,*this);
return *this;
}
bool CWTNumber::operator>(const CWTNumber& n)
{
return WTCompare(n)==;
}
bool CWTNumber::operator>=(const CWTNumber& n)
{
return WTCompare(n)!=-;
}
bool CWTNumber::operator<(const CWTNumber& n)
{
return WTCompare(n)==-;
}
bool CWTNumber::operator<=(const CWTNumber& n)
{
return WTCompare(n)!=;
}
bool CWTNumber::operator==(const CWTNumber& n)
{
return WTCompare(n)==;
}
bool CWTNumber::operator!=(const CWTNumber& n)
{
return WTCompare(n)!=;
}

使用演示:

#include <stdio.h>
#include "WTNumber.h" int main()
{
char sz1[]="";
char sz2[]="";
puts("请输入两个数字:");
while(scanf("%s%s",sz1,sz2)!=-)
{
CWTNumber n1(sz1),n2(sz2);
printf("两数相加结果:\n%s\n",(n1+n2).ToString());
printf("两数相减结果:\n%s\n",(n1-n2).ToString());
printf("两数相乘结果:\n%s\n",(n1*n2).ToString());
printf("两数相除结果:\n%s\n",(n1/n2).ToString());
puts("请输入两个数字:");
}
return ;
}

C++大数精度计算(带小数点)的更多相关文章

  1. php的精度计算问题(bcadd和bcsub)

    一.前言 我们在进行php开发的时候经常会遇到浮点型的问题,特别是涉及金额的部分,常常需要进行加减运算.当小数点的位数比较多的时候,往往容易犯一些很低级的错误.这里记录一下php的精度计算和封装的小d ...

  2. js限制文本框只能输入整数或者带小数点[转]

    这篇文章是关于js限制文本框只能输入整数或者带小数点的内容,以下就是该内容的详细介绍. 做表单验证的时候是否会碰到验证某个输入框内只能填写数字呢,仅允许输入整数数字或者带小数点的数字.下面这段代码也许 ...

  3. C# 正则表达式 验证:数字、带小数点数字、电话和手机

    一.带小数点数字 public static bool IsNumber(string input) { string pattern = "^-?\\d+$|^(-?\\d+)(\\.\\ ...

  4. (译)iPhone: 用公开API创建带小数点的数字键盘 (OS 3.0, OS 4.0)

    (译)iPhone: 用公开API创建带小数点的数字键盘 (OS 3.0, OS 4.0) 更新:ios4.1现在已经将这个做到SDK了.你可以设置键盘类型为UIKeyboardTypeDecimal ...

  5. C#中两个整数相除得到带小数点的结果

    有时候需要将两个整数相除,获得带小数点的float类型数.例如一个整数12345,需要变成123.45.常见与串口与硬件通讯,DSP处理浮点型比较麻烦,DSP传递来的温度等数据都以整型的方式传递,串口 ...

  6. python 带小数点时间格式化

    #获取带小数点的时间>>> import datetime #当前时间加3天 >>> t1 = datetime.datetime.now() + datetime ...

  7. C++算法之大数加法计算的代码

    如下代码段是关于C++算法之大数加法计算的代码,希望对大家有用. { int length; int index; int smaller; int prefix = 0; if(NULL == sr ...

  8. POI 导出excel带小数点的数字格式显示不对解决方法

    最近看到了一个问题就是java导出excel中带小数点的数字显示不对, 比如我想在excel中第一行显示:  3,000.0 但是在excle中导出的格式总是不带小数点 3000(非文本格式),而且也 ...

  9. 五、数据类型(1):整数&&带小数点的数

    1.整数 int printf("%d",...); scanf("%d",&...); 2.带小数点的数 double printf("%f ...

随机推荐

  1. 201521123011 《java程序设计》 第7周学习总结

    1. 本周学习总结 参考资料: XMind 2. 书面作业 1.ArrayList代码分析 1.1 解释ArrayList的contains源代码 1.2 解释E remove(int index)源 ...

  2. 201521123042 《Java程序设计》第3周学习总结

    1. 本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识组织起来.请使用纸笔或者下面的工具画出本周学习到的知识点.截图或者拍照上传. 2. 书面作 ...

  3. Mybatis第八篇【一级缓存、二级缓存、与ehcache整合】

    Mybatis缓存 缓存的意义 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题. myba ...

  4. mongodb 在windows下面进行分片

    在mongodb里面存在另一种集群,就是分片技术,跟sql server的表分区类似,我们知道当数据量达到T级别的时候,我们的磁盘,内存就吃不消了,针对这样的场景我们该如何应对. 一:分片 mongo ...

  5. 字符、字符集、编码,以及它们python中会遇到的一些问题(下)

    在看了很多的博客文章之后,总结整理得到了以下文章,非常感谢这些无私奉献的博主! 文章末尾有本文引用的文章的链接,如果有漏掉的文章引用,可以发邮件联系我,随后再次附上链接! 侵删!!! 这一部分是下篇, ...

  6. oracle 数据库(表)的逻辑备份与恢复

    一.介绍逻辑备份是指使用工具export将数据对象的结构和数据导出到文件的过程.逻辑恢复是指当数据库对象被误操作而损坏后使用工具import利用备份的文件把数据对象导入到数据库的过程.物理备份即可在数 ...

  7. AngularJS -- 提供者(Providers)

    点击查看AngularJS系列目录 转载请注明出处:http://www.cnblogs.com/leosx/ 每个Web应用程序都是有多个对象组合.协作来完成任务的.这些对象需要被实例化,并且连接在 ...

  8. servlet文件上传2——复合表单提交(数据获取和文件上传)

    上传文件时表单enctype属性必须要更改为<enctype='multipart/form-data'>:采用post提交表单,元素需要有name属性: 利用第三方jar包(common ...

  9. HCatalog

    HCatalog HCatalog是Hadoop中的表和存储管理层,能够支持用户用不同的工具(Pig.MapReduce)更容易地表格化读写数据. HCatalog从Apache孵化器毕业,并于201 ...

  10. Codeforces Round #425 (Div. 2)C

    题目连接:http://codeforces.com/contest/832/problem/C C. Strange Radiation time limit per test 3 seconds ...