我有3个值全部四舍五入到没有小数位(即5%,25%,70%),除了我的70%真的是70.6%所以它达到71%,这使得我的总数为5%,25%, 71%= 101%,这是不好的,特别是因为我有一个条形图,如果它超过100%宽度,真的搞砸了。
如何确保我的3个值永远不会超过100%? 现在我使用Math.Round(值,0)是否有任何开关/选项可以用来保持我的3个值的总和超过100%?
由于
答案 0 :(得分:11)
如果三个值总是必须总和为100,那么只对两个值进行舍入,并用
计算第三个值third = 100 - Math.Round(a) - Math.Round(b);
注意:您的结果也可能太小。如果您有三个值为33.333333,则舍入并添加它们将产生99!
编辑(回应@ BlueRajaDannyPflughoeft的评论)
如果您有许多值,则所有舍入错误的总和可能会变大。因此,将它转移到最后一个值不是一个好主意。对于这些情况,我建议连续四舍五入。
double[] values = new double[] { 17.2, 3.7, 4.6, 5.8 };
int[] percent = new int[values.Length];
double sum = values.Sum();
int totalPercent = 100;
for (int i = 0; i < values.Length; i++) {
double rawPercent = sum == 0 ? 0 : values[i] / sum * totalPercent;
sum -= values[i];
int roundedPercent = (int)Math.Round(rawPercent);
totalPercent -= roundedPercent;
percent[i] = roundedPercent;
}
// values = { 17.2, 3.7, 4.6, 5.8 }
//
// Percents:
// percent => { 55, 12, 15, 18 }
// raw (exact) => { 54.952, 11.821, 14.696, 18.530 } (rounded to 3 decimals)
// raw continuous => { 54.952, 11.809, 14.596, 18.000 }
它并不完美,但错误不应超过1%。这是另一个例子
values = { 10.0, 10.0, 10.0, 10.0, 10.0, 10.0 }
Percents:
rounded => { 17, 17, 16, 17, 16, 17 }
raw (exact) => { 16.667, 16.667, 16.667, 16.667, 16.667, 16.667 }
raw continuous => { 16.667, 16.600, 16.500, 16.667, 16.500 17.000 }
答案 1 :(得分:5)
不要添加舍入值并期望得到任何有意义的东西。添加未包含的值。如果那不符合你的要求,你必须通过添加舍入值来解释你认为你正在完成的事情。
答案 2 :(得分:2)
如果你不在乎这些值总和小于 100,那么简单的解决方案就是在整个过程中使用Math.Floor
。
如果你想要向上/向下舍入并且结果正好为100,那就更有趣了。这是一种方法 - 将它们全部向下舍入,然后选择性地将它们向上舍入到最大分数第一,直到再次达到100:< / p>
public static void RoundTo100Percent(IList<double> list)
{
// get the sort order before changing any items
IList<int> sortOrder = list.Select((n, i) => new { Key = n - Math.Truncate(n), Index = i }).OrderByDescending(ki => ki.Key).Select(ki => ki.Index).ToList();
// round them all down to start with
for (int i = 0; i < list.Count; i++)
{
list[i] = Math.Floor(list[i]);
}
// then round them up selectively, starting with those with the highest fractional part
// e.g. 5.9 will round up to 6.0 before 7.8 rounds up to 8.0.
int numberOfItemsToRoundUp = 100 - (int)list.Sum();
foreach (int sortIndex in sortOrder.Take(numberOfItemsToRoundUp))
{
list[sortIndex]++;
}
}
答案 3 :(得分:1)
你不能像这样在最后做检查:
if (total > 100)
total = 100;
答案 4 :(得分:1)
好吧,如果你不圆,那么他们都会加起来达到100%。使用浮点数/双打/小数。问题解决了。
毕竟,为什么你要降低你的准确度? - 顺便说一句,这就是舍入。
答案 5 :(得分:0)
最好将所有帐户四舍五入,然后将剩余余额作为“统计四舍五入”或类似内容。
答案 6 :(得分:0)
为什么不将所有3个值加在一起,然后围绕最终结果? 33.3 + 33.3 + 33.3 = 99.9然后舍入到100,单独舍入只会出现在99,因为每个都会向下舍入。
答案 7 :(得分:0)
当我不得不将数据导入到一个系统中时,这个问题就出现了,这个系统要求每个用户的行集合的整数百分比都要加到100个。
重要的是要意识到没有正确的&#39;这样做的方式。例如,给定三个值,每个等于1/3,舍入总数等于99,应该加1哪个值以强制总数为100?没有正确的答案。只需选一个。
这是我在PHP中的解决方案:
function ensureColumnAddsToOneHundred(&$rows, $columnIndex)
{
$percentagesTotalError = getColumnTotal($rows, $columnIndex) - 100;
if ($percentagesTotalError > count($rows))
{
throw new Exception('Percentages total rounding error larger than nValues!');
}
// Add or subtract one from as many rows as is
// necessary to ensure that the total is exactly 100.
for ($i = 0; $i < abs($percentagesTotalError); ++$i)
{
$rows[$i][$columnIndex] += ($percentagesTotalError > 0)? -1: 1;
}
if (getColumnTotal($rows, $columnIndex) != 100)
{
throw new Exception('Percentages total not equal to 100 even after corrections!');
}
}