2012-06-13 64 views
1

我有一個非常大的數字,千位數的順序,我必須將其轉換爲它的二進制表示。這些數字存儲爲字符串。將一個非常大的數字從十進制字符串轉換爲二進制表示?

由於很少有語言有基本的數據類型來處理這麼大的數字,所以我看不出有什麼簡單的方法可以將它轉換爲可以將其轉換爲整數值的簡單方法。

難道有人請幫助我嗎?這樣做有什麼可行的方法?

+0

想想之間的關係10^x和2^x的片刻... – Junuxx

+0

我不知道是否有任何簡單的方法。在Java BigInteger源代碼中,它會將幾個數字轉換爲整數,並通過在大整數上進行乘法和加法將其「積累」到二進制表示中(即,在可以執行字符串之前,必須對大整數執行乘法+加法操作轉換)。 – nhahtdh

+0

@mattegod。如果你有這種感覺,對不起。無論如何,我已經知道了。感謝所有偉大的幫助。:int'string_to_binary(int bin [],char s []) // int len = strlen(s); int res = 0; int bits = 0; int digits; for(digits = 0; s [digits]; digits ++)s [digits] - ='0'; int firstdigit = 0; int留下; int i; (i = firstdigit,remain = 0; i frodo

回答

26

如果這是一個真正的問題,那麼有很多BigNum庫可以幫助您,例如MPIR庫。

如果這是你不能使用第三方庫的東西,它還是比較容易的。您實際上並不需要這是一個複雜的BigNum庫,您只需要一個操作:除以二。

以下是您的操作方法。從一堆空白的二進制數字開始。然後循環,直到數字爲「0」(是的,這仍然是一個字符串)。如果數字的最後一位數字是奇數,則將1推入堆棧,否則推0.然後將數字除以2並重新啓動循環。

一旦循環結束(編號爲「0」),一次一個地將數字從堆棧中彈出並打印出來。你走了。


哦,對了,除以二,即拼圖:-)

一個比較重要的一塊讓我們先從「12345」。這是您遵循的過程,使用僞代碼。

Set next_additive to 0. 
For every digit in number (starting at the left): 
    Set additive to next_additive. 
    If the digit is odd, set next_additive to 5, else set it to 0. 
    Divide the digit by two (truncating) then add additive. 
Remove leading zero if necessary (if it starts with 0 but is not just 0). 

這可以通過一次處理實際字符串一個字符來完成。

  • 1開始(從12345),添加劑是0,數量爲奇數,所以next_additive是5。將1除以2並添加0的添加劑,即可得到002345

  • 下一位數字2,添加劑是5,數量是偶數,所以next_additive是0。將2除以2並添加5的添加劑,即可得到606345

  • 下一個數字3,加法是0,數字是奇數,所以next_additive是5。將3除以2並添加0的添加劑,即可得到106145

  • 下一個數字4,添加劑是5,數量是偶數,所以next_additive是0。將4除以2並添加5的添加劑,即可得到706175

  • 下一位數字5,加法是0,數字是奇數,所以next_additive是5。將5除以2並添加0的添加劑,即可得到206172

  • 去掉前導零:6172。自從截斷結果​​以來,請忽略下一個添加項。

那裏你有它:12345/2 = 6172


舉例來說,下面是一個Python方法來實現這個算法,如下所示。首先用於檢查字符串數是否奇數的支持例程(請記住,這不是意思是是Pythonic代碼,只是爲了說明它是如何完成的 - 幾乎可以肯定有更好的方法可以在Python中執行此操作,但是這不一定會很好地映射到另一種語言):

def oddsToOne(s): 
    if s.endswith('1'): return 1 
    if s.endswith('3'): return 1 
    if s.endswith('5'): return 1 
    if s.endswith('7'): return 1 
    if s.endswith('9'): return 1 
    return 0 

然後分割字符串數由兩個另一支持程序:

def divByTwo(s): 
    new_s = '' 
    add = 0 

    for ch in s: 
     new_dgt = (ord(ch) - ord('0')) // 2 + add 
     new_s = '%s%d' % (new_s, new_dgt) 
     add = oddsToOne(ch) * 5 

    if new_s != '0' and new_s.startswith('0'): 
     new_s = new_s[1:] 

    return new_s 

最後,一些實際的代碼,以二進制來自十進制字符串的字符串:

num = '12345' 

if num == '0': 
    stack = '0' 
else: 
    stack = '' 
    while num != '0': 
     stack = '%d%s'%(oddsToOne(num), stack) 
     num = divByTwo (num) 

print(stack) 

請注意,如果您想實際使用它來填充真實位(而不是創建一串位),那麼更改ifelse子句中會發生什麼很簡單。

如上所述,它可能不是你能想到的高效或美麗的Python代碼,但它只是爲了展示過程,而不是一些精心設計的生產就緒代碼片段。輸出是(與下面的一些附加的東西,以顯示這是怎麼回事):

12345 
11000000111001 
||  ||| | 
||  ||| +-  1 
||  ||+----  8 
||  |+----- 16 
||  +------ 32 
|+------------- 4096 
+-------------- 8192 
       ===== 
       12345 

因爲這個工程上的數字的字符串表示,不存在任意的數字限制,例如64位的大小位整數。一些示例值(稍微重新格式化爲32位數據塊的可讀性):

123456781234567812345678 
=> 11010001001001001101100000011011 
    01110110001110110010110110101111 
    0111101001110 

99999999999999999999999999999999 
99999999999999999999999999999999 
99999999999999999999999999999999 
9999 
=> 10010010010011010110100100101100 
    10100110000110111110011101011000 
    01011001001111000010011000100110 
    01110000010111111001110001010110 
    01110010000001000111000100001000 
    11010011111001010101010110010010 
    00011000010001010100000101110100 
    01111000011111111111111111111111 
    11111111111111111111111111111111 
    11111111111111111111111111111111 
    1111111111111 
+0

你有什麼想法將二進制轉換回十進制字符串? – ivenxu

+1

@paxdiablo,這是一個很好的答案。謝謝。 – Denis

+0

這不會工作,如果輸入十進制字符串非常大。因爲如果十進制字符串非常大,它不能被表示爲一個數字,因此它不能被2除。試試這個:「123456781234567812345678」。 – derek

相關問題