实用算法实现-第 24 篇 高精度整数运算
来源:互联网 发布:ubuntu 16.04 u盘安装 编辑:程序博客网 时间:2024/05/08 20:15
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// 1234567890123456789int 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// 1234567890struct 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
- 实用算法实现-第 24 篇 高精度整数运算
- 实用算法实现-第 26 篇 模运算
- C++的高精度整数加法运算算法
- 高精度整数运算
- 高精度整数运算
- 实用算法实现-第 25 篇 最大公约数
- 整数高精度算法
- 高精度整数运算改进版
- 高精度整数运算改进版
- 高精度整数运算改进版
- 实用算法实现-第 11 篇贪心算法
- 超长整数的基础运算 算法实现之准备篇
- 超长整数的基础运算 算法实现自平方篇
- 大整数运算乘法(高精度运算)
- 大整数运算(高精度运算)
- 重载“+-*/”实现高精度运算
- 实用算法实现-第 5 篇二分查找树
- 实用算法实现-第6篇线段树
- 决策树算法——ID3算法,C4.5算法
- iPad UIPopoverController弹出窗口的位置和坐标——终结篇
- 调试程序总结
- Twitter Storm简介与入门
- 常用的webservice接口
- 实用算法实现-第 24 篇 高精度整数运算
- 【网摘】Linux 下 C语言大文件读写(大于4G)
- Java Split String
- GUI自动化测试原理剖析—JAVA测试篇
- 【转载】Java中this与super的几种用法与区别
- java笔记:关于复杂数据存储的问题--基础篇:数组以及浅拷贝与深拷贝的问题(上)
- 实用算法实现-第 25 篇 最大公约数
- Java编程中影响性能的一些特点
- 第十三章:字符串 《Thinking in java》学习笔记