实用算法实现-第 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值