The calculation is being done conceptually wrong. It’s not just a rounding problem. Although rare, only not rounding can give difference the same way because at a point there at the end of the precision can give a minimum difference in some cases (it will not happen when percentages are integer).
In fact I think this method is still conceptually wrong because it meets a conceptually wrong definition. It is wrong and may even be illegal in specific cases to parcel a value this way with arbitrary percentages (in some cases it may). In general the most correct is to say the number of plots and the criterion of what to do with the difference that in many cases will occur. This difference is usually 1 or a few cents.
The criterion can be put in the first, the last, if it is more than a penny put in the first as distributed as possible, or in the last, and can even detail what to do when there is difference even in the distribution, although rare can even say specific positions, in some cases has legislation regulating it. In some cases one accepts difference for more or less by own legislation or convention, but in this particular case it is not what one wants. So this method is just a basis of how to solve, note that it is fixed that the difference is in the last.
The most correct would be to validate if the sum of the percentages is 100, but I preferred to let the programmer do it right since you usually do unit tests. One of the advantages of this type of test is that if it is done right avoids cost of performance to validate the argument. Tests like this have disadvantages also that nobody talks, but this is another subject.
Companies and programmers in general do not understand how the routines of their operation should work and are always at risk of government fines, contracts or having other problems.
using static System.Console;
using System.Collections.Generic;
public class Program {
public static void Main() {
foreach (var item in CalculaPercentuais(377.17M, new decimal[] { 33.0M, 33.0M, 34.0M })) WriteLine(item);
}
public static IEnumerable<decimal> CalculaPercentuais(decimal valor, IEnumerable<decimal> percentuais) {
var valores = new List<decimal>();
foreach (var percentual in percentuais) valores.Add(decimal.Round(valor / 100.0M * percentual, 2));
var soma = 0.0M;
for (var i = 0; i < valores.Count - 1; i++) soma += valores[i];
valores[valores.Count - 1] = valor - soma;
return valores;
}
}
Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.
What is your problem? it is returning integer values ?
– Joy Peter