实用算法实现-第 24 篇 高精度整数运算

高精度算法——高精度减法 高精度减法也同加法一样,也是用于位数太大的运算,给你一个十几位的数你可能会做直接开个long long 的数据类型就解决了,但是给你一个100位的呢,1000位的呢,开long long 也不够了,所以就要用高精度了,也就是高精度算法就是处理位数很大数据。 如果你对高精度加法也不是很熟悉你可以看这个(高精度算法——高精度加法)... 阅读详情

24.1    高精度整数加法

24.1.1   实例

PKU JudgeOnline, 1503, Integer Inquiry.

24.1.2   问题描述

给定一组超长的正整数(100位),求出它们的和。

24.1.3   输入

123456789012345678901234567890

123456789012345678901234567890

123456789012345678901234567890

0

24.1.4   输出

370370367037037036703703703670

24.1.5   分析

写一个高精度的加法就可以了。这个题目的测试比较弱,或者说我曾经写的程序的错误很难通过这个题目的测试找出。因为在调试PKU JudgeOnline, 1131, Octal Fractions的程序的时候发现了这个高精度加法的一些bug,虽然它能通过这个题目的测试。

24.1.6   程序

#include<cstdio>
#include<string.h>
long s[10000005];
#define __int64Max 3037000499
//9223372030926249001 = 3037000499^2
//9223372036854775808 = 2^63
//9223372037000250000 = 3037000500^2
#define MultiplyMaxDigit 8
#define AddMaxDigit 18
#define maxNum 7
#define AddMaxNum 1000000000000000000
//               1234567890123456789
int main(){
     __int64num[maxNum];
     __int64 sum[maxNum];
     charstr[102];
     int numTop;
     int sumTop;
     int length;
     int i;
     int carry;
     memset(sum, 0, sizeof(sum));
     sumTop = 0;
     while(scanf("%s", str) && strcmp(str, "0") != 0)
     {
         length = strlen(str);
         numTop = 0;
         memset(num, 0, sizeof(num));
         while(length> AddMaxDigit)
         {
              length = length - AddMaxDigit;
              sscanf(str + length, "%I64d", &num[numTop++]);
              str[length] = '\0';
         }
         sscanf(str, "%I64d",&num[numTop]);
         if(sumTop<= numTop)
         {
              sumTop = numTop;
         }
         carry = 0;
         for(i =0; i <= numTop; i++){
              sum[i] = num[i] + sum[i] + carry;
              carry = 0;
              if(sum[i]> AddMaxNum)
              {
                   sum[i] -= AddMaxNum;
                   carry = 1;
              }
         }
         if(carry== 1)
         {
sumTop++
              sum[sumTop] = 1;
         }
     }
     printf("%I64d",sum[sumTop]);
     for(i =sumTop - 1; i >= 0; i--){
         printf("%018I64d",sum[i]);
     }
     printf("\n");
     return 1;
}

24.2    高精度整数乘法

24.2.1   实例

PKU JudgeOnline, 1131, Octal Fractions

24.2.2   问题描述

实现八进制的小数到十进制的小数的转化,也即完成:0.d1d2d3 ...dk [8] = 0.D1D2D3 ... Dm [10]。

24.2.3   输入

0.75

0.0001

0.01234567

24.2.4   输出

0.75[8] = 0.953125 [10]

0.0001[8] = 0.000244140625 [10]

0.01234567 [8] =0.020408093929290771484375 [10]

24.2.5   分析

这个题目的测试也不是那么苛刻,因为不用高精度也能做。做着个题目的最大收获就是:随机测试是非常必要的。

24.2.6   程序

#include<cstdio>
#include<string.h>
#include<iostream>
using namespace std;
#define ONLINE_JUDGE 0
#define __int64Max 3037000499
//9223372030926249001 = 3037000499^2
//9223372036854775808 = 2^63
//9223372037000250000 = 3037000500^2
#define MultiplyMaxDigit 9
//#define AddMaxDigit 18
#define maxNum 1000
/*
#define AddMaxNum 1000000000000000000
//               1234567890123456789
*/
#define MultiplyMaxNum 1000000000
//                    1234567890
struct largeInt{
     int top;
     __int64num[maxNum];
};
void addLargeInt(largeInt *adder1, largeInt *adder2, largeInt*sum1)
{
//adder和sum可以是同一个指针
     int sumTop;
     __int64sum[maxNum];
     int carry;
     int i;
     memset(sum, 0, sizeof(sum));
     sumTop = (*adder1).top;
     if(sumTop< (*adder2).top)
     {
         sumTop = (*adder2).top;
     }
     carry = 0;
     for(i = 0;i <= sumTop; i++){
         sum[i] = (*adder1).num[i] +(*adder2).num[i] + carry;
         carry = 0;
         if(sum[i]>= MultiplyMaxNum)
         {
              sum[i] -= MultiplyMaxNum;
              carry = 1;
         }
         if(sum[i]>= MultiplyMaxNum)
         {
              cout << "error" << endl;
         }
     }
     if(carry ==1)
     {
         sumTop++;
         sum[sumTop] = 1;
     }
     memcpy(&((*sum1).num), sum, sizeof(sum));
     (*sum1).top = sumTop;
}
void multLargeInt(largeInt *mult1, largeInt *mult2, largeInt*product1)
{
//adder和sum可以是同一个指针
     intproductTop;
     __int64product[maxNum];
     __int64carry;
     int i;
     int j;
     int k;
     memset(product, 0, sizeof(product));
     productTop = (*mult1).top + (*mult2).top +1;
     carry = 0;
     for(i = 0;i <= productTop; i++){
         if(i<= (*mult1).top){
              j = i;
         }else{
              j = (*mult1).top;
         }
         product[i] = carry;
         carry = 0;
         for(; j>= 0; j--){
              k = i - j;
              if(k> (*mult2).top)
              {
                   break;;
              }
              product[i] += (*mult1).num[j] *(*mult2).num[k];
              if(product[i]> MultiplyMaxNum)
              {
                   carry += product[i] /MultiplyMaxNum;
                   product[i] = product[i] %MultiplyMaxNum;
              }
         }
     }
     if(carry !=0)
     {
         product[productTop++] = carry;
     }
     while(product[productTop]== 0 && productTop != 0)
     {
         productTop--;
     }
     memcpy(&((*product1).num), product, sizeof(product));
     (*product1).top = productTop;
}
void printLargeInt(largeInt *num)
{
     int i;
     printf("%I64d",(*num).num[(*num).top]);
     for(i =(*num).top - 1; i >= 0; i--){
         printf("%09I64d",(*num).num[i]);
     }
}
void sprintLargeInt(largeInt *num, char* dst)
{
     int i;
     int length;
     sprintf(dst, "%I64d",(*num).num[(*num).top]);
     for(i =(*num).top - 1; i >= 0; i--){
         length = strlen(dst);
         sprintf(dst + length,"%09I64d", (*num).num[i]);
     }
}
int main(){
     #ifndefONLINE_JUDGE    
        FILE *fin;
    
       fin = freopen("t.in", "r", stdin );
       if( !fin )
       {
              printf( "reopen in filefailed...\n" );  
              while(1){}
              return 0;
       }
        freopen( "ttest.out","w", stdout );
     #endif
 
     charstr[1000];
     charbuff[1000];
     int length;
     largeInt constant;
     largeInt power;
     largeInt sum;
     largeInt adder;
     intlength1;
     int i;
     int start;
     while(scanf("%s", str) != EOF)
     {
         length = strlen(str);
         for(start= 2; str[start] == '0'; start++){
              ;
         }
         start++;
         memset(&constant.num, 0, sizeof(constant.num));
         constant.num[0] = 125;
         constant.top = 0;
         memset(&power.num, 0, sizeof(power.num));
         power.num[0] = 1;
         power.top = 0;
         memset(&sum.num, 0, sizeof(sum.num));
         sum.top = 0;
         for(i =0; i < length - 2; i++)
         {
              multLargeInt(&constant,&power, &power);
         }
         constant.num[0] = 8;
         for(i =length - 1; i >= start - 1; i--){
              memset(&adder.num, 0, sizeof(adder.num));
              adder.top = 0;
              adder.num[0] = str[i] - '0';
              multLargeInt(&adder,&power, &adder);
              addLargeInt(&adder, &sum,&sum);
              multLargeInt(&constant,&power, &power);
         }
         printf("%s[8] = ", str);
         printf("0.");
         //printLargeInt(&sum);
         sprintLargeInt(&sum, buff);
         length1 = strlen(buff);
         if(strcmp(buff,"0") != 0)
         {
              for(i= 0; i < (length - 2) * 3 - length1; i++)
              {
                   printf("0");
              }
              for(;length1 > 0; length1--){
                   if(buff[length1- 1] != '0')
                   {
                       break;
                   }
              }
              buff[length1] = '\0';
              printf("%s",buff);
         }
         printf("[10]\n");
     }
     #ifndefONLINE_JUDGE     
       fclose( stdin );
     #endif
     return 1;
}
本文章欢迎转载,请保留原始博客链接http://blog.youkuaiyun.com/fsdev/article

c++大整数类的几种实现方法与解析 在oj上做题时,相信大家遇到过很多要求大整数的题目,这时候,我们就需要用到所谓的高精度算法,即用数组来储存整数,模拟四则运算以及其他常见的运算,下面就让我们来分析一下几种实现大整数的方法 一.用vector来储存大整数 #include #include #include #include #include #include using namespace std; class Big 阅读详情

相关推荐

大整数运算

这里写目录标题一级目录二级目录三级目录大整数运算大整数运算加法减法高精度与低精度乘法高精度与低精度除法高精度乘高精度A+B(高精度)题目描述输入格式输出格式输入输出样例A*B(高精度)题目描述输入格式输出格式输入输出样例说明/提示 一级目录 二级目录 三级目录 大整数运算 在C语言中,最大整型变量的范围在−9×1018→9×1018-9\times10^{18}\to9\times 10^{18}−9×1018→9×1018。 有时候题目中数据的大小超过最大整型变量,我们不能用C语言自带的变量类型,只能模拟

Lp_2019的博客 343

算法竞赛入门经典 5.2.3高精度运算类bign(BigN)

#include #include #include const int maxn = 1000; struct bign{ int len; int s[maxn]; bign(){ memset(s, 0, sizeof(s)); len = 1; } bign(int num){ *this = num; } bign(const char *num){ *this

Ice He's Note 978

【分治算法之大整数乘法】---C++实现

题目 大整数乘法:用分治算法编程实现两个n位十进制大整数的乘法运算。 一种较为流行的思路(即分治) 分析 <大整数的乘法> 在计算机中,长整形(long int)变量的范围不能超过10位数。 即便用双精度(double)变量,也仅能保证16位有效数字的精度。在某些需要更高精度的乘法运算场合,需要用别的办法来实现运算。 比较容易想到的是做多位数乘法时列竖式进行计算的方法, 只要写出模拟这一过程的程序,就能实现任意大整数的乘法运算。 经过查阅资料,找到一种更易于编程的方法, 即“列表法”。

追光者♂:记录、分享、总结、提升,现象级专栏《Python从入门到人工智能》作者,无惧黑暗,坚信曙光 7677

以顺序表存储的大整数运算

大整数运算的实现原理  写一个BigInt(大整数)类,其中数据成员是一个顺序表,用来保存大整数.其方法是将数的每一位数(0~9中的一个)存放在每一个节点中,高位存放在高下标,低位存放在低下标.注意:实现时下标是从1开始的.类中的运算如Add(), Sub()等全用友元函数来实现.类中还有一些辅助的函数,如push_back(), push_front()等是用BigInt的数据成员调用了顺序表中的

FD1247的博客 2581

高精度加减计算(链表)

运用双向链表进行高精度计算,加减,乘除在完善中。

高精度加减法运算C++源代码

面向过程化C++高精度加减法运算,实现任意长度实数的加减法运算,适合初学C++~~

高精度运算类bign

高精度运算类bign Bign 1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 ...

weixin_34297300的博客 247

任意长的整数进行加法运算

利用双向循环链表实现长整数的存储,每个结点含一个整形变量。任何整形变量的范围是 -(2^15 - 1)~ (2^15 - 1)。输入和输出形式:按中国对于长整数的表示习惯,每四位一组,组间用逗号隔开。 这是我用java写的,使用了双向循环链表,编译环境是myeclipse 8.0,可以运行,有人机交互界面,其中包含源代码,rar文件,还有报告。希望大家多多批评,提出建议,互相学习。

大整数类BIGN的设计与实现 C++高精度模板

众所周知,C++中储存能力最大的unsigned long long 也是有着一个上限,如果我们想计算非常大的整数时,就不知所措了,所以,我写了一个高精度类,允许大整数的四则运算 这个类利用字符串进行输入输出,并利用数组进行储存与处理,通过模拟四则运算,可以计算很大的整数的加减乘除比大小。 支持负数,前导零,支持字符串、整型赋值,支持流输入输出

harryguo2012的专栏 4672

大整数加减乘除指数运算课程设计数据结构(源代码+实验报告,期末成绩优秀)

密码学分为两类密码:对称密码和非对称密码。对称密码主要用于数据的加/解密,而非对称密码则主要用于认证、数字签名等场合。非对称密码在加密和解密时,是把加密的数据当作一个大的正整数来处理,这样就涉及到大整数的加、减、乘、除和指数运算等,同时,还需要对大整数进行输出。请采用相应的数据结构实现大整数的加、减、乘、除和指数运算,以及大整数的输入和输出。 【基本要求】 1.要求采用链表来实现大整数的存储和运算,不允许使用标准模板类的链表类(list)和函数。 同时要求可以从键盘输入大整数,也可以文件输入大整数,大整数可以输出至显示器,也可以输出至文件。大整数的存储、运算和显示,可以同时支持二进制和十进制,但至少要支持十进制。大整数输出显示时,必须能清楚地表达出整数的位数。测试时,各种情况都需要测试,并附上测试截图;要求测试例子要比较详尽,各种极限情况也要考虑到,测试的输出信息要详细易懂,表明各个功能的执行正确。 2.要求大整数的长度可以不受限制,即大整数的十进制位数不受限制,可以为十几位的整数,也可以为500多位的整数,甚至更长;大整数的运算和显示时,只需要考虑正的大整数。如果可能的话,请以秒为单位显示每次大整数运算的时间。 3.要求采用类的设计思路,不允许出现类以外的函数定义,但允许友元函数。主函数中只能出现类的成员函数的调用,不允许出现对其它函数的调用。 4.要求采用多文件方式:.h文件存储类的声明,.cpp文件存储类的实现,主函数main存储在另外一个单独的cpp文件中。如果采用类模板,则类的声明和实现都放在.h文件中。 5.不强制要求采用类模板,也不要求采用可视化窗口;要求源程序中有相应注释。 6.要求采用Visual C++ 6.0及以上版本进行调试。

任意精度整数加减法计算器

该程序可以计算任意精度的加减法计算,结果以每三位隔开

高精度bign

第5章  基础题目选解  第 119 页  struct bign {      int len,s[maxn];      bign() { memset(s, 0, sizeof(s)); len = 1; } };  其中,len表示位数,而s数组就是具体的各个数字。  上面的结构体中有一个函数,称为构造函数(Constructor)。构造函数是C++中特有的,作用是进行初始化。

cccrown的专栏 848

【初阶】手把手教你轻松上手Denodo | 连接数据库并创建基本视图 (二)

在本教程的第二部分,我们将涵盖:连接到数据库,与创建基本视图。

Denodo的博客 1106

大整数的高精度运算(加减乘除移位)

突破数据类型限制

m0_70865803的博客 1870

重装系统后,恢复Oracle的.ORA文件

前几天,系统莫名奇妙产生很多宏病毒,进而感染整个C盘,不得已,格式化后重装了系统。 重装系统之后,突然想到D盘中的oracle中很多数据没导出来备份,安装文件下有很多有用的.ORA文件,抱着死马当活马医的态度,居然成功了。 1、将原来D盘(D:\oracle\product\10.2.0\oradata\orcl)下的数据文件备份下其他盘,将D盘的oracle目录名改成oracle1。安装数据

zhanggnol的blog 5551

绕过限制?实测修改UA在PC端运行微信小程序的可行性及风险

本文探讨了通过修改User-Agent(UA)在PC端运行微信小程序的技术可行性及风险。分析了小程序设备限制的技术原理,包括`wx.getSystemInfo`API和UA检测机制,并提供了多种修改方案及其局限性。同时强调了潜在的安全和法律风险,推荐使用官方模拟器或安卓模拟器等更安全的替代方案。

weixin_30879169的博客 363

高精度算法之大数运算

思想: 先用字符串来读入大整数,然后用数组来存储大整数。与上一篇的所讲思路不同的是,这次是数组的每一个元素对应大整数的一个数,从而模拟手算过程。 主要实现思路与手算无太大差别。主要是一些细节上。 统一做个说明:模拟大数的数组的第零个元素保存的是数字个数(不包括第零个元素),而且数组从1到尾分别存大数的低位到高位,刚好相反。 在运算过程中的对齐操作全以此为标准。 读入时统一处理:...

b10221001的博客 290

告别切换烦恼!用Parallels Desktop的Host-Only网卡,在macOS上直接访问虚拟机里的公司内网

本文详细介绍了如何在macOS上使用Parallels Desktop的Host-Only网卡直接访问虚拟机内的公司内网,告别频繁切换操作系统的烦恼。通过配置Host-Only网络模式,实现主机与虚拟机的安全高效通信,特别适合需要频繁访问内网资源的IT从业者。文章包含分步指南、自动化脚本和常见问题解决方案,帮助用户优化工作流程。

weixin_28739079的博客 363

C++高精度算法的实现

做ACM题的时候,经常遇到大数的加减乘除,乘幂,阶乘的计算,这时给定的数据类型往往不够表示最后结果,这时就需要用到高精度算法。高精度算法的本质是把大数拆成若干固定长度的块,然后对每一块进行相应的运算。这里以考虑4位数字为一块为例,且输入的大数均为正整数(也可以考虑其他位,但要注意在每一块进行相应运算时不能超出数据类型的数值范围;高精度除法有两种,一种是高精度除以低精度,另一种是高精度除以高精度。后者则考虑用高精度减法来实现,即每次减去高精度除数,直到减到小于除数,则减的次数即为商,剩余的即为余数。

m0_74824496的博客 435

K8s认证文件丢失的应急处理与恢复策略

本文详细介绍了Kubernetes(K8s)认证文件丢失时的应急处理与恢复策略。从快速诊断问题范围到不同场景的临时解决方案,再到深度恢复方案(无损重建、部分重置、完全重建),提供了全面的操作指南。同时强调了生产环境中的防丢失设计、高可用集群的特殊处理以及日常运维建议,帮助运维人员有效应对认证文件丢失的紧急情况。

weixin_33743248的博客 327

AD18软件——捕捉栅格、电气栅格、可见栅格的意义及设置

本文介绍了PCB设计中的三种栅格功能:可视栅格用于辅助定位(快捷键Shift+Ctrl+G),捕捉栅格控制光标移动间距(快捷键G),电气栅格实现元件自动吸附(快捷键Shift+E)。同时提供了在Altium Designer中快速查找相同网络标号的两种实用方法:Alt+鼠标单击或双击网络。这些功能可显著提高PCB设计效率和准确性。

qq_37999850的博客 645

高精度算法之大整数类

思想: 由于编程语言提供的基本数值数据类型表示的数值范围有限,不能满足较大规模的高精度数值计算,因此需要利用其他方法实现高精度数值的计算,于是产生了大数运算。大数运算主要有加、减、乘三种方法。 考虑用数组存储整数,并模拟手算的方法进行加减乘除四则运算。为了能像int一样方便的使用大整数,可以定义结构体,大整数类。 结构体BigInteger可用于存储高精度非负整数。这里存储的方案是...

b10221001的博客 481

2024年12月中国电子学会青少年软件编程(Python)等级考试试卷(六级)答案 + 解析

2024年12月中国电子学会青少年软件编程(Python)等级考试试卷(六级)答案 + 解析

伶俐角少儿编程 729

高精度算法快速入门(C++代码示例)

高精度算法是处理大整数运算的重要技术,当数字超出标准数据类型(如int、long long)的表示范围时,这种算法就显得尤为重要。

m0_74013450的博客 1230

092、Python在芯片验证中的应用:从脚本小子到验证架构师

Python在芯片验证中的高效应用 本文通过实际案例展示了Python在芯片验证中的关键作用。凌晨三点的调试场景揭示了传统方法的局限,Python脚本能在20分钟内分析80GB波形数据定位FIFO指针问题。文章重点介绍了两个核心工具: 智能日志分析系统:通过正则表达式和上下文分析,自动分类百万行验证日志中的错误,生成可视化报告,效率远超传统grep方法。 寄存器模型生成器:将Excel表格自动转换为UVM寄存器模型代码,将原本需要两周的手工工作缩短至两小时,同时保证零错误。 文章还展示了Python与Sys

z534437748的博客 72

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

上一篇: 实用算法实现-第 23 篇 最大流
下一篇: 实用算法实现-第 25 篇 最大公约数
存储李希
博客等级 码龄15年 418粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值