從大數運算所想到的

2021-09-30 10:59:30 字數 3945 閱讀 4690

[cpp]view plain

copy

#define shrt_min    (-32768)        /* minimum (signed) short value */

#define shrt_max      32767         /* maximum (signed) short value */

#define ushrt_max     0xffff        /* maximum unsigned short value */

#define int_min     (-2147483647 - 1) /* minimum (signed) int value */

#define int_max       2147483647    /* maximum (signed) int value */

#define uint_max      0xffffffff    /* maximum unsigned int value */

#define long_min    (-2147483647l - 1) /* minimum (signed) long value */

#define long_max      2147483647l   /* maximum (signed) long value */

#define ulong_max     0xfffffffful  /* maximum unsigned long value */

#define llong_max     9223372036854775807i64       /* maximum signed long long int value */

#define llong_min   (-9223372036854775807i64 - 1)  /* minimum signed long long int value */

#define ullong_max    0xffffffffffffffffui64       /* maximum unsigned long long int value */

/*寫這篇文章之前,先說下一下背景,最初的時候,是準備寫大數運算的,當然大數運算大家都寫爛了,我自然是先借鑑了網上的諸多材料,才開始準備寫。然而很不幸出師未捷身先死,還沒有切入演算法,就在準備工作上除了諸多問題,總算花了乙個下午的時間解決了所有問題,接著今天的空閒時光寫出這篇日誌*/

大數運算,顧名思義,就是很大的數值的數進行一系列的運算。在c

語言中定義的資料型別都是存在最大儲存值的,在

limits.h

中有定義

從上面可以看出在c

語言(在我的機器上)中可以儲存的最大的數是

unsigned long long 

,也只能達到

2^17-1

的最大值。那麼比這更大數怎麼辦呢?這就牽扯到大數怎麼儲存的問題了。使用相應的資料結構來儲存資料,使用諸如陣列,鍊錶甚至是樹來儲存大數。就是解決這類問題的方法。最初的選擇主要是在陣列與鍊錶中考慮。

如果使用鍊錶的話,那麼未來在計算數的時候,必須不停的移動指標,來完成計算,效率未免過低/*

以上存疑

*/。  那麼使用陣列呢?這時候就有許多東西需要考慮了,大尾儲存,還是小尾儲存。/*

感興趣的請自行

google little-endian

和big-endian*/

還是考慮對於運算的效率。對於進製運算而言,先從低位運算開始,將進製與後邊的數進行運算,這個時候如果考慮小尾的儲存方式更為的合理。但是在陣列之中仍是標準的儲存方式。

/*後來想想如果採用

vector

會不會更為的合理*/

[cpp]view plain

copy

#define array_size 10

typedef

struct

largenumber  

* plargenumber;  

在這裡重點要聊一聊#define array_size 10

由於使用了巨集定義,就會出現了乙個重要的問題那就是陣列的大小被固化,在這我們可以使用柔性陣列

[cpp]view plain

copy

typedef

struct

largenumber  

* plargenumber;  

有興趣的朋友可以看看這個**

當然在初始化的時候依舊要使用malloc 

和realloc

來擴充套件指標。當然嫌麻煩的可是直接使用指標

unsined long long * array;/*

好吧我承認,我應該在這裡用

vector*/

有了定義,就應該有初始化函式了

[cpp]view plain

copy

bool

largenumberinit(plargenumber* p)  

(*p)->length = 0;  

return

true

;  }  

}  

那麼接下來的問題就到了如何讀取資料了。既然是大數,那麼傳統的cin

和sprinf 

自然而然的被我放棄了

/*其實我試過的無法單獨的讀取某個數

*/。採用

getchar()

迴圈讀取字元,在將字元轉化位數字。

備選思路如下:

1.普大喜奔的位運算,16

位的16

進製數的

unsigned long long 

讀取乙個

16進製制數,採用左移的方式來讀入乙個數中。陣列中的每一位都採用這樣的方式來儲存。

2.依舊是16

位的做法這一次採用讀取滿乙個

16進製制位,放入字串中然後進行轉化。

3.讀取的是10

進製數的字元,將其存入字串中,讀取滿特定位數後,將其轉化為數字。

最後本人採用了最後一種方法,原因在於在stdlib.h

中有atoll

()這樣的轉化函式/*後來證明這個方向是錯的*/

[cpp]view plain

copy

plargenumber largenumberputin(plargenumber pnum)  

doi++;  

}    

}  while

((number!=

'#') && (i!=nodesize*array_size));  

return

pnum;  

}  

首先讀取第乙個數,判斷其是否是符號位。再迴圈中執行下列過程讀取19

個數字放置在預先準備好的字串陣列中,在使用

atoll

函式轉化。但是在

vs中不存在

atoll

()函式。同時使用

atoll

返回值是

long long ,

#define llong_max     9223372036854775807i64 

好吧我定義的的array_node_max

是這個值

#define array_node_max 9999999999999999999//比

ullmax

少一位

目測只能自己寫這個函式了。

[cpp]view plain

copy

unsigned 

long

long

atoll(

char

* buffer)  

return

number;  

}  

就這樣所有的準備工作都已經就緒,緊接著的就是大數運算咯。

制衡技術,從Adblock所想到的

這是乙個很特別的東西.可能已經有人發現了它,但是它並非被廣泛接受.對於這個技術的思考 主要是在安裝了adblock後想到的.這種反作用力的技術,很可能是一片藍海.而這種技術的產生及推廣,對未來社會及科技的變化是不可預料的.先說adblock,這是乙個反廣告技術,當然很可能你已經安裝了,或許你還不太清...

從裝mac mini ssd硬碟所想到的

買一台mac mini,準備裝乙個ssd硬碟,加快執行速度,由於考慮到直接配置的 太高,不如買乙個其低配版本的mac mini主機,自己買乙個ssd新增進去來的實惠 於是從 買了乙個硬碟線,按照網路的教程進行自己裝機。從 賣家那裡看到店家的拆機教程,配齊了拆機工具,就開始進行拆機了 在拆機的過程中,...

制衡技術,從Adblock所想到的

這是乙個很特別的東西.可能已經有人發現了它,但是它並非被廣泛接受.對於這個技術的思考 主要是在安裝了adblock後想到的.這種反作用力的技術,很可能是一片藍海.而這種技術的產生及推廣,對未來社會及科技的變化是不可預料的.先說adblock,這是乙個反廣告技術,當然很可能你已經安裝了,或許你還不太清...