2012-02-08 45 views
3

我有兩個整數變量,partialtotal。這是一個進步,所以partial從零開始,逐一上升到total的值。劃分兩個整數而不鑄造爲雙倍

如果我想表明的進展分數值(從0.0到1.0),我可以做到以下幾點:

double fraction = double(partial)/double(total); 

但如果總太大,以雙倍的轉換可能會丟失信息。

實際上,丟失信息的數量是可以忍受的,但我想知道是否有一個算法或std函數來獲得兩個值之間的分數損失較少的信息。

+3

'double'有一個53位的尾數 - 你是說總數可能> 53位? – 2012-02-08 17:05:02

+6

「partial」和「total」的數據類型是什麼? IIRC'double'可以保持32位整數的任何值,但不會降低準確性。 – 2012-02-08 17:05:36

+1

那麼'total'需要有一個大於'> 2^53'的值,大約是十進制的16位數字。我真的很想知道你是否有這麼大的數字。在這種情況下,我希望你的整數是64位寬,否則它們首先就不夠用。 – 2012-02-08 17:11:02

回答

7

顯而易見的答案是將partial乘以某個比例因子; 100是一個常用的選擇,因爲除法後百分比爲 整數值(向下舍入)。問題是,如果值爲 這麼大,以至於它們不能精確表示爲double,那麼 也是一個很好的機會,即由比例因子的乘法將溢出 。 (對於這個問題,如果它們那麼大,初始值 將在大多數機器上溢出int)。

0

如果你想精確地表示分數,你會得到某種包含分子的結構和分母作爲整數,並且對於唯一表示,您只需將最大公約數(特殊情況爲零)分解出來。如果您擔心重複操作後浮點表示可能不夠準確,那麼您只需找到一些關於數值分析的課程即可,該問題並非嚴格意義上的編程問題。比其他人有更好的方法來計算某些結果,但我不能深入其中(我從來沒有做過課程,只是閱讀它)。

1

是的,有一個算法丟失較少的信息。假設您想要找到最接近分數數學值的double值,則需要一個能夠保存total << 53的整數類型。您可以創建自己的或使用像GMP這樣的庫。然後

  • 規模partial使(total << 52) <= numerator < (total << 53),其中numerator = (partial << m)
  • q是整數商numerator/totalr = numerator % total
  • mantissa = q如果2*r < total= q+1如果2*r > total如果2*r == total,如果你想圓半升mantissa = q+1= q如果你想一輪下降,即使是兩半,如果你想要一半到甚至是
  • result = scalbn(mantissa, -m)

你們中的大多數得到了相同的值(double)partial/(double)total的時候,一個最顯著位的差異可能不是太罕見,兩個或三個LSB差異會也不讓我感到吃驚,但並不多見,一更大的差異是不太可能的(說,有人可能會很快舉例)。

現在,這是值得的努力?通常不會。