我需要爲我正在構建的程序編寫一個會計程序,該程序會給我一個小數的整除分數。因此例如:以整數平分美元金額(十進制)
$143.13/5 =
28.62
28.62
28.63
28.63
28.63
我在這裏看到的文章:Evenly divide in c#,但似乎它僅適用於整數除法。任何想法解決這個問題的優雅解決方案?
我需要爲我正在構建的程序編寫一個會計程序,該程序會給我一個小數的整除分數。因此例如:以整數平分美元金額(十進制)
$143.13/5 =
28.62
28.62
28.63
28.63
28.63
我在這裏看到的文章:Evenly divide in c#,但似乎它僅適用於整數除法。任何想法解決這個問題的優雅解決方案?
計算在一個時間量之一,從總減去各量,以確保你總是有正確的總左:
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
多數民衆贊成在很好的解決方案 – Anurag 2010-01-11 01:48:48
非常酷!當然,對合約的要求。要求(總數> = 0),......分隔符> 0或任何語法使其更加整齊。然後我會單元測試這件事情到死......不傷。單元測試不需要快速運行,因此得到答案,然後對其進行分類,並與預期結果進行比較。此外,我會收益返回的金額,而不是打印在實際的實施。我想添加另一個函數,它返回結果作爲...小數的數組,我想。既然你知道分頻器,你可以分配所需的確切大小的數組。 – 2010-01-11 02:10:22
謝謝,這看起來像一個不錯的,優雅的解決方案! – Amberite 2010-01-11 02:24:15
你可以在你引用的問題中使用算法,通過乘以100,使用整數均分功能,然後將每個結果除以100(假設你只想處理2個dp,如果你想要3DP多1000等)
與尼克的迴應一樣,這將損失幾美分(在給出的例子中) – danben 2010-01-11 01:31:54
如果您有保證恰好兩個精度數字,這個東西(僞)的浮動:
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:讓我知道這是不是你想要的。
浮動壞是壞壞...應該永遠不會推薦浮動 – 2010-01-11 01:38:53
OP說他是以浮動開始並不是我的錯。如果您不屑於閱讀我的回覆,而不是盲目地進行修改,您會發現我立即轉換爲int。 – danben 2010-01-11 01:45:26
看看這個問題:What is the best data type to use for money in c#?
等一下!你想確保沒有一分錢會丟失,對嗎?
可以解決這(在美分),而構建一個數組:
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;
不知道爲什麼我是第一個投票。我認爲這是做這件事最直觀,最有效的方法。 – Ponkadoodle 2010-01-11 02:27:35
+1,這是我的答案,但更好。 – danben 2010-01-11 03:17:30
+1。這在數據庫函數中對我來說非常有用,其他基於循環的解決方案將成爲性能問題。 – dpw 2015-04-17 15:50:14
它更容易對付岑TS。我建議你將14313分成5個相等的部分,而不是143.13。它給你2862和剩下的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);
}
您也可以將整個餘數添加到第一個或最後一個條目。最後,根據會計需要,還可以爲剩餘部分創建單獨的交易。
也可以使用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--;
}
}
整數除法是你所需要的。你不應該使用花車來賺錢。 – 2010-01-11 01:22:09
你能詳細說明一下嗎? – Amberite 2010-01-11 01:25:27
十進制是在這裏使用的正確類型(與浮點數不同) – justinlatimer 2010-01-11 01:27:16