2013-01-04 102 views
-1

假設您有一個非常長的二進制字(> 64位),它表示無符號整數值,並且您想打印實際的數字。我們談論C++,讓我們假設你有一個布爾[]的std ::矢量<布爾>的std :: bitset的,並用STD最終:: string的或開始某種std :: ostream - 無論您的解決方案更喜歡什麼。但請僅使用核心語言和STL。打印非常長的二進制表示的整數值

現在,我懷疑,你必須對它進行深入評估,以獲得一些中間結果,這些結果足夠小以便存儲 - 最好是基數10,如x&middot; 10 k。我可以想出從這一點來組裝數字。但由於沒有對應於10的基數的塊寬度,我不知道該怎麼做。當然,你可以從任何其他的塊寬度開始,比如說3,以x&middot;(2 )k的形式獲得中間體,然後將其轉換爲基數10,但這會導致x&middot ; 10 3&middot; k&middot; lg2顯然具有浮點指數,這沒有任何幫助。

無論如何,我已經用盡了這個數學垃圾,我會很感激一個深思熟慮的建議。

此致,
阿明

+1

「二進制到十進制轉換」或類似的搜索堆棧溢出。但請注意,一般來說,每個十進制數字都依賴於每個二進制數字。 –

+1

這個問題比你想象的要難得多。我會說使用一個bignum庫來完成任務,或者放棄。否則,你必須實施並做大量的bidnum劃分和模數來得到答案。允許舍入嗎?如果允許舍入,那麼很容易將其轉換爲「double」。 –

+0

@MooingDuck它不能那麼辛苦,可以嗎?你之前嘗試過嗎? –

回答

1

我會假設你已經有某種BIGNUM師/模功能一起工作,因爲實施這樣的事情是一個完整的噩夢。

class bignum { 
public: 
    bignum(unsigned value=0); 
    bignum(const bignum& rhs); 
    bignum(bignum&& rhs); 
    void divide(const bignum& denominator, bignum& out_modulo); 
    explicit operator bool(); 
    explicit operator unsigned(); 
}; 

std::ostream& operator<<(std::ostream& out, bignum value) { 
    std::string backwards; 
    bignum remainder; 
    do { 
     value.divide(10, remainder); 
     backwards.push_back(unsigned(remainder)+'0'); 
    }while(value); 
    std::copy(backwards.rbegin(), backwards.rend(), std::ostream_iterator(out)); 
    return out; 
} 

如果四捨五入是一個選項,它應該是相當瑣碎最大數轉換爲double爲好,這將是一個LOT更快。也就是說,將64個最高有效位複製到一個unsigned long,將其轉換爲double,然後乘以2.0乘以有效位數減去64的冪(我說的是有效位,因爲必須跳過任何前導零)
因此,如果您有150個有效位,將頂部64複製到unsigned long,將其轉換爲double,然後乘以std::pow(2.0, 150-64)〜7.73e + 25得到結果。如果你只有40位有效位,右邊的零填充它仍然有效。將40位複製到unsigned long的MSB,將其轉換爲double,然後乘以std::pow(2.0, 40-64)〜5.96e-8得到結果!

編輯

奧利查爾斯沃思張貼在Double Dabble一個鏈接到維基百科頁面吹滅第一算法我展示出來的水。我不覺得傻。

+0

+1,因爲你從經驗中發表意見。 –

+0

-1。你不需要這一切。當然不是劃分。 –

+0

@SethCarnegie:雖然我從經驗講,但這並不意味着wisdon。 Oli Charlesworth發佈了一個關於如何在線性時間內完成的鏈接,而不是我瘋狂的慢速方法。 –