2011-03-28 20 views
4

我有一個雙重的,不一定是積極的,但通常。它可以是0.xxxx000或X.xxxx00000或XX.00000或0.xxx0xxx00000,最後在最後一個數字的右邊都有0。我需要跟蹤有多少數字。我一直有這個麻煩,有什麼幫助嗎?這是C.鑑於一個雙重的,需要找到總共有多少位數

+0

你試過了什麼?你可以做一些事情,你可以從字符串形式的double的每一端計數零個零,然後計算兩個迭代器之間的差異以得到你的計數嗎? – Anon 2011-03-28 13:15:03

+0

我試過循環,我試圖分隔每個數字,直到只有0.0000000000 ..保持,但它似乎從來沒有比較0.000000 ...正確,從未停止。然後我從另一個方向嘗試減去並乘以數字,直到減法命中0,但大量的邊緣情況破壞 – cdietschrun 2011-03-28 13:28:03

+2

1.0/3的結果中有多少位數?任何雙重計算都是一樣的。 *您*選擇數字的位數。 – 2011-03-28 13:37:10

回答

5

用sprintf把它變成一個字符串,做任何計數/測試你需要在數字

+1

sprintf最多隻能轉換一些可能被格式說明符的精度參數覆蓋的默認數字位數。例如。 'sprintf(s,「%。7f」,x);' - 會在'。'後面轉換成7位數字。所以使用sprintf絕對不是一個解決方案。 – 2011-03-28 13:22:06

+0

好點,我在想,有一些可能的精度問題。 – jonsca 2011-03-28 13:23:04

+0

@Serge Dundich:那麼爲什麼不'sprintf(s,「%.50f」,x);'?當然,這個問題並不完全清楚(特別是考慮到你描述的基準2和基準10問題),但是jonsca的回答可能是提問者正在尋找的東西。 – tomlogic 2011-03-28 15:30:54

5

雙有52個尾數位加上一個隱含的「1」比特做,所以你應該能夠打雙精度指針到一個64位整數(將原始位變成一個整數),& =這與(1 < < 52)-1和| =結果(1 < 52) 。

該log10將是小數位數。雖然,我幾乎傾向於說「與jonsca的解決方案一起」,因爲它非常簡單(在任何情況下都值得+1)。

+0

恩,非常感謝。儘管如此,位移也可以很好並且很快。 「 – jonsca 2011-03-28 13:33:16

+0

」該log10將是小數位數。「沒有!它不會。考慮一下這個例子:1 + 1/2^52。多少個小數位?正確的答案是52.但log10(2^52 + 1)遠遠低於那個。 – 2011-03-28 14:31:27

+0

_any number_的base-N對數是以base-N計數的位數。或者,更準確地說,應該說ceil(log-N),因爲顯然沒有「小數位」(如果計算4.1位數,即5)。你的例子1 + 1/2^52不適用,因爲這個數字在雙精度上不能正確表示。另外,IEEE 754 double是衆所周知的有16位重要小數(或更少),你的數字52不能以任何方式正確。 – Damon 2011-03-28 14:52:00

2

double的表示不是小數 - 它是二進制的(就像計算機中的所有其他數字一樣)。你定義的問題確實沒有意義。考慮這個例子:數字1.2被轉換爲二進制 - 1 + 1/5 = 1.(0011)二進制[0011]。如果你將它的精度降至52位(雙精度) - 你將得到1.0011001100110011001100110011001100110011001100110011等於1+(1-1/2^52)/ 5的二進制值。如果以十進制形式表示這個數字,那麼您將在全零之前得到52個小數,這比16位數的double的最大小數精度要大得多(並且所有那些從17到52的表示的數字都沒有意義) 。

無論如何,如果你有純粹抽象的問題(如學校):

int f(double x) 
{ 
    int n = 0; 

    x = fabs(x); 
    x -= floor(x); 

    while(x != floor(x)) 
    { 
    x *= 2; 
    ++n; 
    } 

    return n; 
} 

該函數返回的二進制位數全零之前,它也是(的全零之前的小數位數如果返回值> 0,則最後的小數位總是5)。

相關問題