hdu Exponentiation高精度实数乘幂(用了带小数的高精度模板)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <cstdlib>
#define INT_BIT_MAX 100
#define FLOAT_BIT_MAX 100 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);
}; 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) != ;
}
char s[];
char ss[];
char ans[];
int n;
int main()
{
while (scanf("%s %d", s, &n) != EOF)
{
CWTNumber x(s);
CWTNumber y("");
for (int i = ; i < n; i++)
{
y = y * x;
}
//printf("%s\n", y.ToString());
strcpy(ss, y.ToString()); if (ss[] == '')
{
printf("%s\n", ss + );
}
else
printf("%s\n", ss);
}
return ;
}
hdu Exponentiation高精度实数乘幂(用了带小数的高精度模板)的更多相关文章
- HDU ACM 1063 Exponentiation 大实数乘方
分析:大实数乘方计算. #include<iostream> #include<string> using namespace std; struct BigReal //高精 ...
- HDU 2255 奔小康赚大钱(带权二分图最大匹配)
HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...
- java高精度实数和小数
java 高精度实数和小数 String s = "1231222222222222222222222222222222222222222222222222222222"; Big ...
- Pencil-一个开源免费的UI原型工具,自带ios和android模板
Pencil是一个开源免费的UI原型工具,自带ios和android模板,可以很方便的做mockup. 下图是一个官方展示的模板:
- Java除法结果带小数、进一法的实现 Java问题通用解决代码
http://blog.csdn.net/windone0109/article/details/5355379进一法: 即省略的位上只要大于零都要进一位 : 四舍五入法: 即省略的位上小于五都要舍 ...
- HDU 2838 (DP+树状数组维护带权排序)
Reference: http://blog.csdn.net/me4546/article/details/6333225 题目链接: http://acm.hdu.edu.cn/showprobl ...
- HDU Exponentiation 1063 Java大数题解
Exponentiation Time Limit: 1000/500 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- HDU 1829 A Bug's Life 【带权并查集/补集法/向量法】
Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes ...
- HDU - 5973 Game of Taking Stones (威佐夫博弈 高精度)
题目描述: Two people face two piles of stones and make a game. They take turns to take stones. As game r ...
随机推荐
- JS判断客户端是手机还是PC的2个代码
搬了下砖 function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = ["Android", & ...
- LeetCode 533----Lonely Pixel II
问题描述 Given a picture consisting of black and white pixels, and a positive integer N, find the number ...
- 自定义View和ViewGroup(有这一篇就够了)
为了扫除学习中的盲点,尽可能多的覆盖Android知识的边边角角,决定对自定义View做一个稍微全面一点的使用方法总结,在内容上面并没有什么独特的地方,其他大神们的博客上面基本上都有讲这方面的内容,如 ...
- linux 加jre环境变量
1.vi /etc/profile 2.未行添加 export JAVA_HOME=/usr/local/java export CLASSPATH=.:$JAVA_HOME/lib/tools.ja ...
- C语言二级指针(指向指针的指针)
转载:http://c.biancheng.net/cpp/html/85.html 指针可以指向一份普通类型的数据,例如 int.double.char 等,也可以指向一份指针类型的数据,例如 in ...
- Spring中的转换器:Converter
配置spring的配置文件: <bean id="conversionService" class="org.springframework.context.sup ...
- C# winfrom DataGridView用法
DataGridView列的宽度自动调整,可以使用DataGridView.AutoSizeColumnsMode属性实现. 下面的代码就是列的宽度根据Header和所有单元格的内容自动调整的. // ...
- [翻译] PQFCustomLoaders
PQFCustomLoaders Current version: 0.0.1 Collection of highly customizable loaders for your iOS proje ...
- Google官方教程之Selling In-app Products
1.原文链接[需FQ]:http://developer.android.com/training/in-app-billing/index.html 2.平时对于英文文档都是大概读一下,现在翻译文章 ...
- [T-ARA][SEXY LOVE]
歌词来源:http://music.163.com/#/song?id=22704402 作曲 : 新沙洞老虎/崔圭成 [作曲 : 新沙洞老虎/崔圭成] [作曲 : 新沙洞老虎/崔圭成] 作词 : 新 ...