2010-01-11 64 views
14

我需要爲我正在構建的程序編寫一個會計程序,該程序會給我一個小數的整除分數。因此例如:以整數平分美元金額(十進制)

$143.13/5 = 

28.62 
28.62 
28.63 
28.63 
28.63 

我在這裏看到的文章:Evenly divide in c#,但似乎它僅適用於整數除法。任何想法解決這個問題的優雅解決方案?

+0

整數除法是你所需要的。你不應該使用花車來賺錢。 – 2010-01-11 01:22:09

+0

你能詳細說明一下嗎? – Amberite 2010-01-11 01:25:27

+5

十進制是在這裏使用的正確類型(與浮點數不同) – justinlatimer 2010-01-11 01:27:16

回答

29

計算在一個時間量之一,從總減去各量,以確保你總是有正確的總左:

decimal total = 143.13m; 
int divider = 5; 
while (divider > 0) { 
    decimal amount = Math.Round(total/divider, 2); 
    Console.WriteLine(amount); 
    total -= amount; 
    divider--; 
} 

結果:

28,63 
28,62 
28,63 
28,62 
28,63 
+2

多數民衆贊成在很好的解決方案 – Anurag 2010-01-11 01:48:48

+3

非常酷!當然,對合約的要求。要求(總數> = 0),......分隔符> 0或任何語法使其更加整齊。然後我會單元測試這件事情到死......不傷。單元測試不需要快速運行,因此得到答案,然後對其進行分類,並與預期結果進行比較。此外,我會收益返回的金額,而不是打印在實際的實施。我想添加另一個函數,它返回結果作爲...小數的數組,我想。既然你知道分頻器,你可以分配所需的確切大小的數組。 – 2010-01-11 02:10:22

+0

謝謝,這看起來像一個不錯的,優雅的解決方案! – Amberite 2010-01-11 02:24:15

1

你可以在你引用的問題中使用算法,通過乘以100,使用整數均分功能,然後將每個結果除以100(假設你只想處理2個dp,如果你想要3DP多1000等)

+0

與尼克的迴應一樣,這將損失幾美分(在給出的例子中) – danben 2010-01-11 01:31:54

2

如果您有保證恰好兩個精度數字,這個東西(僞)的浮動:

amount = amount * 100 (convert to cents) 
int[] amounts = new int[divisor] 
for (i = 0; i < divisor; i++) amounts[i] = amount/divisor 
extra = amount % divisor 
for (i = 0; i < extra; i++) amounts[i]++ 

,然後做任何你想要的amounts,這是在美分 - 你可以轉換回浮動如果你絕對必須或格式爲美元和美分。

如果不明確,所有這些都不僅僅是平均分配一個浮動價值,而是儘可能平均分配一個貨幣金額,因爲美分是一個不可分割的美元單位。對於OP:讓我知道這是不是你想要的。

+3

浮動壞是壞壞...應該永遠不會推薦浮動 – 2010-01-11 01:38:53

+4

OP說他是以浮動開始並不是我的錯。如果您不屑於閱讀我的回覆,而不是盲目地進行修改,您會發現我立即轉換爲int。 – danben 2010-01-11 01:45:26

26

可以解決這(在美分),而構建一個數組:

int a = 100 * amount; 
int low_value = a/n; 
int high_value = low_value + 1; 
int num_highs = a % n; 
int num_lows = n - num_highs; 
+0

不知道爲什麼我是第一個投票。我認爲這是做這件事最直觀,最有效的方法。 – Ponkadoodle 2010-01-11 02:27:35

+0

+1,這是我的答案,但更好。 – danben 2010-01-11 03:17:30

+0

+1。這在數據庫函數中對我來說非常有用,其他基於循環的解決方案將成爲性能問題。 – dpw 2015-04-17 15:50:14

3

它更容易對付岑TS。我建議你將14313分成5個相等的部分,而不是143.13。它給你2862和剩下的3個。你可以將這個餘數分配給前三個部分或任何你喜歡的方式。最後,將美分轉換回美元。

另請注意,您將始終獲得小於所需零件數的餘數。

3

首先,請確保您不使用浮點數來表示美元和美分(請參閱其他文章爲什麼,但簡單的原因是並非所有的十進制數都可以表示爲浮點數,例如$ 1.79 )。

下面是做這件事的一種方法:

decimal total = 143.13m; 
int numberOfEntries = 5; 
decimal unadjustedEntryAmount = total/numberOfEntries; 
decimal leftoverAmount = total - (unadjustedEntryAmount * numberOfEntries); 
int numberOfPenniesToDistribute = leftoverAmount * 100; 
int numberOfUnadjustedEntries = numberOfEntries - numberOfPenniesToDistribute; 

所以,現在你有未調整金額28.62,然後你必須決定如何分配剩餘。你可以分配一個額外的一分錢給每一個開始在頂部或底部(看起來像你想從底部)。

for (int i = 0; i < numberOfUnadjustedEntries; i++) { 
    Console.WriteLine(unadjustedEntryAmount); 
} 

for (int i = 0; i < numberOfPenniesToDistribute; i++) { 
    Console.WriteLine(unadjustedEntryAmount + 0.01m); 
} 

您也可以將整個餘數添加到第一個或最後一個條目。最後,根據會計需要,還可以爲剩餘部分創建單獨的交易。

1

也可以使用C#迭代器生成,使Guffa's answer更方便:

public static IEnumerable<decimal> Divide(decimal amount, int numBuckets) 
{ 
    while(numBuckets > 0) 
    { 
     // determine the next amount to return... 
     var partialAmount = Math.Round(amount/numBuckets, 2); 
     yield return partialAmount; 
     // reduce th remaining amount and #buckets 
     // to account for previously yielded values 
     amount -= partialAmount; 
     numBuckets--; 
    } 
}