C++高精度模板
原文地址:http://blog.csdn.net/wall_f/article/details/8373395
原文只附代码,没有解析,本文增加了一些对代码的解释。
请注意:本模板不涉及实数运算与负数运算,使用减法a-b时请保证, a >= b;所有用本模板来转化的数需保证a >0 && a无小数部分。
引: 
题目中涉及到高精度运算在信息学竞赛中并不少见,很多题目得不到全分就是因为选手不会写高精度模板。尽管AC过高精度(+,*,-,//除法麻烦一点)模板题,但是对于将高精度写入结构体使得可以正常运算的bign模板,很多选手只是有所听闻而不会写。其实写起来并不难,只是将原来那些模板题写入运算符重载即可 。
建议背下来,OI比赛中指不定就撞上了,现推也可以,但是比较慢,至少保证熟练。
运算涉及: 
Bool型:== 、> 、< 、 >= 、 <= 、 != 
赋值语句:= 、 +=、 -=、 *=、 /=、 %= 
运算符:+ 、- 、 * 、 /、 %
其中 (?)= 赋值运算符的重载最为好写,直接调用已经重载完成的(?)运算符,再返回当前this。(? includes + - / %)
其次便是bool型。> < 分别用字符串的比较的比较方式重载,其余的只需要将它们组合一下。例如 == : !(>) && !(<)。
难点在于除法运算符的重载。
我们定义一个结构体包含一个整型int(长度)与数组s(存每一位)组成,其中数组是反着存的。
#include <bits/stdc++.h> 
using namespace std;
const int MAXN = 5005;  
struct bign
{
    int len, s[MAXN];
    bign ()  //初始化
    {
        memset(s, 0, sizeof(s));
        len = 1;
    }
    bign (int num) { *this = num; }
    bign (const char *num) { *this = num; }  //让this指针指向当前字符串
    bign operator = (const int num)
    {
        char s[MAXN];
        sprintf(s, "%d", num);  //sprintf函数将整型映到字符串中
        *this = s;
        return *this;  //再将字符串转到下面字符串转化的函数中
    }
    bign operator = (const char *num)
    {
        for(int i = 0; num[i] == '0'; num++) ;  //去前导0
        len = strlen(num);
        for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0'; //反着存
        return *this;
    }
    bign operator + (const bign &b) const //对应位相加,最为简单
    {
        bign c;
        c.len = 0;
        for(int i = 0, g = 0; g || i < max(len, b.len); i++)
        {
            int x = g;
            if(i < len) x += s[i];
            if(i < b.len) x += b.s[i];
            c.s[c.len++] = x % 10;  //关于加法进位
            g = x / 10;
        }
        return c;
    }
    bign operator += (const bign &b)  //如上文所说,此类运算符皆如此重载
    {
        *this = *this + b;
        return *this;
    }
    void clean()  //由于接下来的运算不能确定结果的长度,先大而估之然后再查
    {
        while(len > 1 && !s[len-1]) len--;  //首位部分‘0’故删除该部分长度
    }
    bign operator * (const bign &b) //乘法重载在于列竖式,再将竖式中的数转为抽象,即可看出运算法则。
    {
        bign c;
        c.len = len + b.len;
        for(int i = 0; i < len; i++)
        {
            for(int j = 0; j < b.len; j++)
            {
                c.s[i+j] += s[i] * b.s[j];//不妨列个竖式看一看
            }
        }
        for(int i = 0; i < c.len; i++) //关于进位,与加法意同
        {
            c.s[i+1] += c.s[i]/10;
            c.s[i] %= 10;
        }
        c.clean();  //我们估的位数是a+b的长度和,但可能比它小(1*1 = 1)
        return c;
    }
    bign operator *= (const bign &b)
    {
        *this = *this * b;
        return *this;
    }
    bign operator - (const bign &b)  //对应位相减,加法的进位改为借1
    {  //不考虑负数
        bign c;
        c.len = 0;
        for(int i = 0, g = 0; i < len; i++)
        {
            int x = s[i] - g;
            if(i < b.len) x -= b.s[i];  //可能长度不等
            if(x >= 0) g = 0;  //是否向上移位借1
            else
            {
                g = 1;
                x += 10;
            }
            c.s[c.len++] = x;
        }
        c.clean();
        return c;
    }
    bign operator -= (const bign &b)
    {
        *this = *this - b;
        return *this;
    }
    bign operator / (const bign &b)  //运用除是减的本质,不停地减,直到小于被减数
    {
        bign c, f = 0; //可能会在使用减法时出现高精度运算
        for(int i = len-1; i >= 0; i--)  //正常顺序,从最高位开始
        {
            f = f*10;  //上面位的剩余到下一位*10
            f.s[0] = s[i];  //加上当前位
            while(f >= b)
            {
                f -= b;
                c.s[i]++;
            }
        }
        c.len = len;  //估最长位
        c.clean();
        return c;
    }
    bign operator /= (const bign &b)
    {
        *this  = *this / b;
        return *this;
    }
    bign operator % (const bign &b)  //取模就是除完剩下的
    {
        bign r = *this / b;
        r = *this - r*b;
        r.clean();
        return r;
    }
    bign operator %= (const bign &b)
    {
        *this = *this % b;
        return *this;
    }
    bool operator < (const bign &b) //字符串比较原理
    {
        if(len != b.len) return len < b.len;
        for(int i = len-1; i != -1; i--)
        {
            if(s[i] != b.s[i]) return s[i] < b.s[i];
        }
        return false;
    }
    bool operator > (const bign &b)  //同理
    {
        if(len != b.len) return len > b.len;
        for(int i = len-1; i != -1; i--)
        {
            if(s[i] != b.s[i]) return s[i] > b.s[i];
        }
        return false;
    }
    bool operator == (const bign &b)
    {
        return !(*this > b) && !(*this < b);
    }
    bool operator != (const bign &b)
    {
        return !(*this == b);
    }
    bool operator <= (const bign &b)
    {
        return *this < b || *this == b;
    }
    bool operator >= (const bign &b)
    {
        return *this > b || *this == b;
    }
    string str() const  //将结果转化为字符串(用于输出)
    {
        string res = "";
        for(int i = 0; i < len; i++) res = char(s[i]+'0')+res;
        return res;
    }
};  
istream& operator >> (istream &in, bign &x) //重载输入流
{
    string s;
    in >> s;
    x = s.c_str();  //string转化为char[]
    return in;
}  
ostream& operator << (ostream &out, const bign &x)  //重载输出流
{
    out << x.str();
    return out;
}
int main()
{
    bign a;//除了声明外其他如整型般使用
    //……
    return 0;
}
感谢原作者。
不妨运用一下: 
luogu P1601 A+B Problem(高精) https://www.luogu.org/problem/show?pid=1601 
luogu  P2142 高精度减法  https://www.luogu.org/problem/show?pid=2142 
luogu P1303 A*B Problem  https://www.luogu.org/problem/show?pid=1303 
luogu P1480 A/B Problem  https://www.luogu.org/problem/show?pid=1480
不妨思考一下其他高精度运算: 
luogu:P2293 [HNOI2004]高精度开根 https://www.luogu.org/problem/show?pid=2293
高精度模板至此结束。 
箜瑟_qi 2017.04.08 9:53
C++高精度模板的更多相关文章
- [Template]高精度模板
		
重新写一下高精度模板(不要问我为什么) 自认为代码风格比较漂亮(雾 如果有更好的写法欢迎赐教 封装结构体big B是压位用的进制,W是每位长度 size表示长度,d[]就是保存的数字,倒着保存,从1开 ...
 - [note]高精度模板
		
高精度模板 先定义一个struct struct gj{ int l,s[N]; bool fh; void Print(){ if(fh)putchar('-'); for(int i=l;i> ...
 - 高精度模板 支持各种运算 c++
		
绪言 自从有了高精度模板,妈妈再也不用怕我不会打高精度了! 代码 代码长度与日俱增啊~~~ #include<iostream> #include<cstring> #incl ...
 - 高精度模板 Luogu P1932 A+B & A-B & A*B & A/B Problem
		
P1932 A+B & A-B & A*B & A/B Problem 题目背景 这个题目很新颖吧!!! 题目描述 求A.B的和差积商余! 输入输出格式 输入格式: 两个数两行 ...
 - Java 大数、高精度模板
		
介绍: java中用于操作大数的类主要有两个,一个是BigInteger,代表大整数类用于对大整数进行操作,另一个是BigDecimal,代表高精度类,用于对比较大或精度比较高的浮点型数据进行操作.因 ...
 - JAVA高精度模板
		
刚开始还坚持用C++写高精来着,后来发现JAVA写高精方便太多了,所以也来学习一下JAVA高精度的模板. 参考:https://www.cnblogs.com/imzscilovecode/p/883 ...
 - 高精度模板 洛谷Luogu P1932 A+B & A-B & A*B & A/B Problem
		
P1932 A+B & A-B & A*B & A/B Problem 题目背景 这个题目很新颖吧!!! 题目描述 求A.B的和差积商余! 输入输出格式 输入格式: 两个数两行 ...
 - [SinGuLaRiTy] 复习模板-高精度模板
		
[SinGuLaRiTy-1042] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 结构体封装 //高精度运算 注意%I64d与%lld # ...
 - XDOJ 1046 - 高精度模板综合测试 - [高精度模板]
		
题目链接:http://acm.xidian.edu.cn/problem.php?id=1046 题目描述 请输出两个数的和,差,积,商,取余.注意不要有前导零. 输入 多组数据,每组数据是两个整数 ...
 
随机推荐
- Java字节流在Android中的使用
			
引言:项目开发有时会使用上传文件到服务器,再从服务器取数据显示到本地这一过程:或者输入一段文字,再把文字显示出来.这个过程都用到了IO流. IO流分为字符流(Reader\Writer)和字节流(In ...
 - eclipse项目导入到android studio中文乱码处理
			
由于eclipse项目是gbk编码,Android studio默认用的是utf-8. 就会导致代码中的汉字,注释全部显示为乱码. 解决方法:在module的bulid.gradle中加入: comp ...
 - iOS开发之UIView的常见属性
			
1.所有控件都继承自UIView,UIView的常见属性如下: @property(nonatomic,readonly) UIView *superview;获得自己的父控件对象 @property ...
 - 在ExpressJS中设置二级域名跨域共享Cookie
			
问题:我使用expressjs和mongostore来管理session.下面是expressjs中的设置. app.configure(function(){ app.use(express.ses ...
 - 利用shell批量改名和linux中取随机数的方法
			
先批量创建文件 #!/bin/sh if [ ! -d /tmp/chenyao ] then mkdir /tmp/chenyao -p fi cd /tmp/chenyao ..} do touc ...
 - webpack使用总结
			
我们可以在js中引入样式文件 require('myStyle.css') 这时我们便需要引入相应的webpack loader来帮助我们解析这段代码. 一般来说需要引入css-loader和styl ...
 - 使用register_shutdown_function触发写日志,使用fastcgi_finish_request提高响应速度
			
公司内部的市场管理系统,一直是我一个人维护,最近老是有开发埋怨,内网的账号被人改了密码,账号被解绑了...哈的,错在这还不是一个完整的系统,既没有严格的权限也没有做操作日志呀... 权限现在是准备做在 ...
 - VB6/VBA中跟踪鼠标移出窗体控件事件(类模块成员函数指针CHooker类应用)
			
一.关于起因 前几天发了一篇博文,是关于获取VB类模块成员函数指针的内容(http://www.cnblogs.com/alexywt/p/5880993.html):今天我就发一下我的应用实例. V ...
 - json解包与json封包
			
首先,对两个名词进行简单的说明: 1.NSData 用来存储二进制的数据类型.NSData类提供了一种简单的方式,它用来设置缓冲区.将文件的内容读入缓冲区,或将缓冲区的内容写到一个文件.不变缓冲区(N ...
 - 如何选择适合自己的CMS建站系统
			
在互联网发展突飞猛进的今天,可谓”得市场者得天下”,而电商已成为占据市场速度最快.范围最广的手段,进而网站建设也逐渐引起商家重视,并深入到了企业和个体的发展战略之中. 如今企业建站已 ...