1. 程式人生 > >實用演算法實現-第 24 篇 高精度整數運算

實用演算法實現-第 24 篇 高精度整數運算

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.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

相關推薦

實用演算法實現- 24 精度整數運算

24.1.1   例項 PKU JudgeOnline, 1503, Integer Inquiry. 24.1.2   問題描述 給定一組超長的正整數(100位),求出它們的和。 24.1.3   輸入 123456789012345678901234567890

實用演算法實現- 14 啟發式搜尋

14.1    A*搜尋 A*(A star)演算法是一種很好的樹搜尋策略,在許多人工智慧的書籍中有所介紹。比如《人工智慧,一種現代方法》和《人工智慧,複雜問題求解的結構和策略》。 [i]文介紹到,A*演算法使用估價函式F(N)來估算從初始狀態S到當前狀態N,再到目標狀態T

【資料結構與演算法】之單鏈表、雙鏈表、迴圈連結串列的基本介紹及其Java程式碼實現---

一、連結串列的基本介紹 連結串列的定義:連結串列是一種遞迴的資料結構,它或者為空(null),或者是指向一個結點(node)的引用,該結點含有一個泛型的元素和一個指向另一條連結串列的引用。----Algorithms  Fourth  Edition   常見的連結串

【資料結構與演算法】之棧的基本介紹及其陣列、連結串列實現---

一、棧的基本介紹 1、棧的基本概念 棧是一種限制在一端進行插入和刪除操作的線性表資料結構。棧中有兩個比較重要的操作:push(壓棧:將元素壓入棧頂)和pop(彈棧:從棧頂彈出一個元素)。都滿足先進後出、後進先出的特點! 從圖中可以看出,我們常把棧的上面稱為棧

【資料結構與演算法】之佇列的基本介紹及其陣列、連結串列實現---

一、佇列的基本概念 1、定義 佇列是一種先進先出的線性表。它只允許在表的前端進行刪除操作,而在表的後端進行插入操作,具有先進先出、後進後出的特點。進行插入操作的一端成為隊尾(tail),進行刪除操作的一端稱為隊頭(head)。當佇列中沒有元素時,則稱之為空佇列。 在

【資料結構與演算法】之排序全家桶(十大排序詳解及其Java實現)---

本篇文章彙總了10種場常見的排序演算法,篇幅較長,可以通過下面的索引目錄進行定位查閱: 7、桶排序 一、排序的基本概念 1、排序的定義 排序:就是使一串記錄,按照其中的某個或者某些關鍵字的大小,遞增或遞減的排列起來

0基礎學演算法 四彈 精度

    今天寫這個的時候心情是非常糟糕的,因為我寫了這篇博文四遍,每次都因為網頁問題,不是需要重新整理就是要重開,以至於我昨天一天和今天上午寫了整整4遍沒提交成功,不嘮嗑了,切入正題。     高精度是一種計算大數的演算法,通常我們計算的時候會用int,要是範圍大了就會

可用配置中心config-server(SVN版)

try cat 註意 address con mat user 環境 文件 一 新建module引入config-server依賴 <dependencies> <dependency> <gr

Windowns API 24 WTSEnumerateSessions 枚舉session信息

服務 set rate urn 空間站 tsa cti brush current 函數原型: BOOL WTSEnumerateSessions( HANDLE hServer,

: 可用的服務註冊中心

第一篇: 服務的註冊與發現(Eureka) 介紹了服務註冊與發現,其中服務註冊中心Eureka Server,是一個例項,當成千上萬個服務向它註冊的時候,它的負載是非常高的,這在生產環境上是不太合適的,這篇文章主要介紹怎麼將Eureka Server叢集化(高可用),效果類似上一篇文章中的

: 可用的分散式配置中心(Spring Cloud Config)

上一篇文章講述了一個服務如何從配置中心讀取檔案,配置中心如何從遠端git 或 本地讀取配置檔案,當服務例項很多時,都從配置中心讀取檔案,這時可以考慮將配置中心做成一個微服務,將其叢集化,從而達到高可用,架構圖如下: 一、準備工作 繼續使用前面文章的工程(註冊中心 leopard-eur

演算法風暴1-陣列中出現次數超過一半的數字

用頭腦風暴學演算法,對於一個問題,我們不只是要解決它,還要去思考有什麼好的方法,差的方法去解決,甚至是一些錯誤的但可以提供思想借鑑的方法。 此問題“陣列中出現次數超過一半的數字”是一道非常經典的演算法題,我把它放在演算法風暴系列第一篇來解析,探討學習一個演算法

【轉載】SpringCloud教程 | : 可用的服務註冊中心

文章 史上最簡單的 SpringCloud 教程 | 第一篇: 服務的註冊與發現(Eureka) 介紹了服務註冊與發現,其中服務註冊中心Eureka Server,是一個例項,當成千上萬個服務向它註冊的時候,它的負載是非常高的,這在生產環境上是不太合適的,這篇

史上最簡單的SpringCloud教程 | : 可用的服務註冊中心(Finchley版本)

文章 史上最簡單的 SpringCloud 教程 | 第一篇: 服務的註冊與發現(Eureka) 介紹了服務註冊與發現,其中服務註冊中心Eureka Server,是一個例項,當成千上萬個服務向它註冊的時候,它的負載是非常高的,這在生產環境上是不太合適的,這篇文章主要介紹怎麼

“毛星雲OpenCV3程式設計入門之python實現讀取視訊+呼叫攝像頭

1.6.1讀取視訊+呼叫攝像頭 # -*- coding: gbk -*- __author__ = 'sunzhilong' import cv2 #讀取視訊,以幀顯示 cap = cv2.VideoCapture("E:/Study/python/Open

“毛星雲OpenCV3程式設計入門之python實現基本圖形繪製

4.3基本圖形繪製 python程式碼: # -*- coding: utf-8 -*- __author__ = 'sunzhilong' import cv2 import numpy as np image = np.zeros((600,600,3

“毛星雲OpenCV3程式設計入門之python實現影象拆分、合併

5.3影象拆分、合併 python程式碼: # -*- coding: utf-8 -*- import cv2 import numpy as np srcImage = cv2.imread("E:/Study/python/OpenCV_study/i

“毛星雲OpenCV3程式設計入門之python實現亮度、對比度

5.4亮度、對比度 python程式碼: # -*- coding: utf-8 -*- import cv2 import numpy as np gcontrastvalue = 80 # 對比度 gbrightvalue = 80

[每日演算法] leetcode24題 Swap Nodes in Pairs、 111題 Minimum Depth of Binary Tree

111. Minimum Depth of Binary Tree 原題目描述 Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along