2013-04-12 65 views
2

這顯然不起作用。從兩個大整數中獲取精確的百分比

BigInteger Total = 1000000000000000000000000000000000000000000000000000022234235423534543; 
BigInteger Actual = 83450348250384508349058934085; 
string Percent = ((Decimal)100.0/Total*Actual).ToString()+"%"; 

問題是,如何得到我的精確百分比?

目前我使用..

 string sTotal = (task.End - task.Start).ToString(); 
     BigInteger current = task.End; 

       string sCurrent = (task.End-current).ToString().PadLeft(sTotal.Length, '0'); 
       Int32 maxLength = sCurrent.Length; 
       if (maxLength > Int64.MaxValue.ToString().Length - 1) 
        maxLength = Int64.MaxValue.ToString().Length - 1; 

       UInt64 currentI = Convert.ToUInt64(sCurrent.Substring(0, maxLength)); 
       UInt64 totalI = Convert.ToUInt64(sTotal.Substring(0, maxLength)); 

       Percent = (Decimal)100.0/totalI 
        * currentI; 

您能否提供更好的?

+2

你想讓它精確到幾個地方? –

+0

我希望你可以使用一些浮點類型而不是BigInteger(有一些額外的魔法)。 – HopeNick

+0

@EricLippert 56位數或更多 – Chris

回答

4

你計算一個合理的,不是整數,所以你應該安裝求解基金會:

http://msdn.microsoft.com/en-us/library/ff524509(v=VS.93).aspx

和使用Rational而不是BigInteger的:

http://msdn.microsoft.com/en-us/library/ff526610(v=vs.93).aspx

你可以然後調用ToDouble,如果你想得到最接近的double值。

我需要精確到56位小數

OK,那就是精確可笑的數額,但我要你的話。

由於雙精度只有15位小數,小數只有29,因此不能使用雙精度或小數。你將不得不親自編寫代碼來完成這個部門。

這裏有兩種方法可以做到這一點:

首先,寫一個算法,模擬做長除法。你可以手工完成,所以你可以編寫一個計算機程序來做到這一點。繼續下去,直到生成所需的精度位數。

二:WOLOG認爲有問題的理性是積極的,是形式x/y其中xy是大的整數。假設b爲10 p以獲得期望的精度p。你希望找到與該屬性的大整數a是:

a * y < b * x 

b * x < (a + 1) * y 

無論a/b(a+1)/b是最接近x/y p位小數。

有意義嗎?

通過對非負BigInteger集合執行二進制搜索,您可以找到值a

要進行二分法搜索,首先必須找到上限和下限。較低很容易;你知道0是一個下限,因爲通過假設x/y分數是正數。要找到上限,請嘗試1/b,10/b,100/b ...依此類推,直到找到大於x/y的值。現在你有一個上限和下限,你可以二進制搜索結果空間,找到確切的值a,使不平等成立。

+0

儘管我不擅長數學,但這至少改進了我現有的解決方案。謝謝你 – Chris

+1

@克里斯:不客氣。我的建議是:善於數學。你會發現它非常有助於你的計算機編程。你明白爲什麼這些不平等會給你所尋找的分數嗎? –