当前位置: 首页 > news >正文

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

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.csdn.net/fsdev/article

转载于:https://www.cnblogs.com/jpa2/archive/2012/01/15/2527899.html

相关文章:

  • PHP Mysql-插入多条数据
  • Windows窗体
  • DataWorks新手引导(持续更新)
  • TOP语句放到表值函数外,效率异常低下
  • 产品经理教你玩转阿里云负载均衡SLB系列(一):快速入门--什么是负载均衡
  • Enum一点使用总结
  • 路由器相关参数及设置
  • 祝网友们龙年快乐!
  • CSS以图换字的9种方法
  • 部署Oracle 11.2.0.3 RAC (二)
  • [WinForm]DataGridView通过代码新增行问题
  • linux下配置SS5(SOCK5)代理服务
  • Spring.net 学习笔记之ASP.NET底层架构
  • stagefright框架 Video Playback的流程
  • EF架构~LinqToEntity里实现left join的一对一与一对多
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • avalon2.2的VM生成过程
  • chrome扩展demo1-小时钟
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • java概述
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • PAT A1050
  • quasar-framework cnodejs社区
  • Spring Cloud Feign的两种使用姿势
  • ubuntu 下nginx安装 并支持https协议
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 计算机在识别图像时“看到”了什么?
  • 前端临床手札——文件上传
  • 强力优化Rancher k8s中国区的使用体验
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • const的用法,特别是用在函数前面与后面的区别
  • ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  • ​人工智能书单(数学基础篇)
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (2)(2.10) LTM telemetry
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (二)windows配置JDK环境
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • .Net Core和.Net Standard直观理解
  • .net core使用RPC方式进行高效的HTTP服务访问
  • .netcore如何运行环境安装到Linux服务器
  • .NET程序员迈向卓越的必由之路
  • .Net的C#语言取月份数值对应的MonthName值
  • .net与java建立WebService再互相调用
  • .Net中wcf服务生成及调用