[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,這是乙個反廣告技術,當然很可能你已經安裝了,或許你還不太清...