四捨五入後　割合率合計100％になる方法 

#四捨五入率後割合百パーセント超え

下記のように、割合はすべて、16.666の場合、

```csharp
levelList = new List<double>() { 16.666, 16.666, 16.666, 16.666, 16.666, 16.666 };
```
 {16.7、16.7、16.7、16.7、16.7、16.7} 四捨五入率後割合合計100％超えちゃいます。

リストが四捨五入率後割合合計100％になる方法を調べました。

最大端数と最小端数のindexを算出、最大端数が0.1になるまで最小端数を移動というやり方で成功しました

#例
###数列：16.666 , 16.666 , 16.666 , 16.666 , 16.666 , 16.666
.初期四捨五入数列：16.7 , 16.7 , 16.7 , 16.7 , 16.7 , 16.7 sum=100.2
.初期端数：-0.0333333333333 , -0.0333333333333 , -0.0333333333333 , -0.0333333333333 , -0.0333333333333 , -0.0333333333333
  LOOP1回目
   hasu_temp1:-0.0333333333333 , -0.0333333333333 , -0.0333333333333 , -0.0333333333333 , -0.0333333333333 , -0.0333333333333
   1番目最小端数:[-0.0333333333333]  1番目最大端数：[-0.0333333333333]
    B 端数すべて同じ max<0 minindex数-add add:0.0666666666667
    -> 移動後：-0.1000000000000 , -0.0333333333333 , -0.0333333333333 , -0.0333333333333 , -0.0333333333333 , -0.0333333333333
    端数を試し計上：16.6 , 16.7 , 16.7 , 16.7 , 16.7 , 16.7 sum=100.1
  LOOP2回目
   hasu_temp2:-0.0333333333333 , -0.0333333333333 , -0.0333333333333 , -0.0333333333333 , -0.0333333333333
   2番目最小端数:[-0.0333333333333]  2番目最大端数：[-0.0333333333333]
    B 端数すべて同じ max<0 minindex数-add add:0.0666666666667
    -> 移動後：-0.1000000000000 , -0.1000000000000 , -0.0333333333333 , -0.0333333333333 , -0.0333333333333 , -0.0333333333333
    端数を試し計上：16.6 , 16.6 , 16.7 , 16.7 , 16.7 , 16.7 sum=100.0
###結果：16.6 , 16.6 , 16.7 , 16.7 , 16.7 , 16.7 sum=100.0

###数列：33.333 , 33.333 , 33.333
.初期四捨五入数列：33.3 , 33.3 , 33.3 sum=99.9
.初期端数：0.0333333333333 , 0.0333333333333 , 0.0333333333333
  LOOP1回目
   hasu_temp1:0.0333333333333 , 0.0333333333333 , 0.0333333333333
   1番目最小端数:[0.0333333333333]  1番目最大端数：[0.0333333333333]
    C 端数すべて同じ max>=0 minindex数+add add:0.0666666666667
    -> 移動後：0.1000000000000 , 0.0333333333333 , 0.0333333333333
    端数を試し計上：33.4 , 33.3 , 33.3 sum=100.0
###結果：33.4 , 33.3 , 33.3 sum=100.0

###数列：33.3 , 33.3 , 33.3 , 0.1
.初期四捨五入数列：33.3 , 33.3 , 33.3 , 0.1 sum=100.0
.初期端数：0.0 , 0.0 , 0.0 , 0.0
###結果：33.3 , 33.3 , 33.3 , 0.1 sum=100.0

###数列：33.3 , 33.3 , 33.3 , 99.999
.初期四捨五入数列：16.7 , 16.7 , 16.7 , 50.0 sum=100.1
.初期端数：-0.0415875016884 , -0.0415875016884 , -0.0415875016884 , 0.0247625050651
  LOOP1回目
   hasu_temp1:-0.0415875016884 , -0.0415875016884 , -0.0415875016884 , 0.0247625050651
   1番目最小端数:[-0.0415875016884]  4番目最大端数：[0.0247625050651]
    A maxindex != minindex 各自maxindex数+add,minindex数-add add:-0.0415875016884
    -> 移動後：0.0000000000000 , -0.0415875016884 , -0.0415875016884 , -0.0168249966233
  LOOP2回目
   hasu_temp2:-0.0415875016884 , -0.0415875016884 , -0.0168249966233
   2番目最小端数:[-0.0415875016884]  4番目最大端数：[-0.0168249966233]
    A maxindex != minindex 各自maxindex数+add,minindex数-add add:-0.0415875016884
    -> 移動後：0.0000000000000 , 0.0000000000000 , -0.0415875016884 , -0.0584124983117
  LOOP3回目
   hasu_temp3:-0.0415875016884 , -0.0584124983117
   4番目最小端数:[-0.0584124983117]  3番目最大端数：[-0.0415875016884]
    A maxindex != minindex 各自maxindex数+add,minindex数-add add:-0.0584124983117
    -> 移動後：0.0000000000000 , 0.0000000000000 , -0.1000000000001 , 0.0000000000000
  LOOP4回目
   hasu_temp4:-0.1000000000001
   3番目最小端数:[-0.1000000000001]  3番目最大端数：[-0.1000000000001]
    B 端数すべて同じ max<0 minindex数-add add:-0.0000000000001
    -> 移動後：0.0000000000000 , 0.0000000000000 , -0.1000000000000 , 0.0000000000000
    端数を試し計上：16.7 , 16.7 , 16.6 , 50.0 sum=100.0
###結果：16.7 , 16.7 , 16.6 , 50.0 sum=100.0

```csharp
        /// <summary>
        /// 割合100%取得
        /// 四捨五入率を合計すると100％になる方法
        /// </summary>
        /// <param name="resultList"></param>
        /// <returns></returns>
        public static List<decimal> GetPercent100(List<double> levelList)
        {
            var total = levelList.Sum();
            var loop_i=1;//計算loop回数
            // 配列
            List<decimal> result_temp = levelList.Select(x=>Convert.ToDecimal( x* 100 / total)).ToList();
            List<decimal> result = result_temp.Select(x=>Math.Round(x, 1, MidpointRounding.AwayFromZero)).ToList();
            Console.WriteLine(".初期四捨五入数列：" + string.Join(" , ", result) + " sum=" + result.Sum());
            List<decimal> result_hasu = result_temp.Zip(result, (t1, t2) => t1 - t2).ToList();
            Console.WriteLine(".初期端数：" + string.Join(" , ", result_hasu));
            if (result.Sum() == 100) { return result; }
            do
            {
                // 最大端数と最小端数のindexを算出
                var result_hasu_temp = result_hasu.Where(i => !(i == 0 || i==Convert.ToDecimal( 0.1 ) || i==Convert.ToDecimal(-0.1))).ToList();
                decimal cnt_hasu = result_hasu_temp.Count();
                decimal max = result_hasu_temp.Max();
                decimal min = result_hasu_temp.Min();
                int maxindex = result_hasu.FindIndex(i => i.CompareTo(max)==0);
                int minindex = result_hasu.FindIndex(i => i == min);
                Console.WriteLine("  LOOP" +loop_i+"回目");
                Console.WriteLine("   hasu_temp"+loop_i+":" + string.Join(" , ", result_hasu_temp));
                if (maxindex != -1)
                {
                    Console.WriteLine("   "+(minindex+1)+"番目最小端数:["+min+"]  "+(maxindex+1)+"番目最大端数：[" +max+"] ");
                    if ((minindex != -1 && maxindex != minindex))
                    {
                        // 最大端数、最小端数の項目は違う
                        // 0.1までの最小調整端数を算出し、最大端数は調整端数を足す、最小端数は調整端数を引く
                        var add = Math.Min((decimal)0.1 - result_hasu[maxindex], result_hasu[minindex]);
                        result_hasu[maxindex] += add;
                        result_hasu[minindex] -= add;
                        Console.WriteLine("    A maxindex != minindex 各自maxindex数+add,minindex数-add add:"+add);
                        Console.WriteLine("    -> 移動後：" + string.Join(" , ", result_hasu));
                    }
                    else if (result_hasu_temp.Average()==max&&result_hasu_temp.Average() ==min
                            && maxindex == minindex)
                    {
                        //端数すべて同じ
                        // 最大端数が0.1になるまで最小端数を移動
                        if (max<0)
                        {
                        　　//端数＜0の場合
                            var add = (decimal)0.1 - Math.Abs(result_hasu[maxindex]);
                            result_hasu[minindex] -= add;
                        Console.WriteLine("    B 端数すべて同じ max<0 minindex数-add add:"+add);
                        }
                        else
                        {
                        　　//端数>=0の場合
                            var add = (decimal)0.1 - Math.Abs(result_hasu[maxindex]);
                            result_hasu[maxindex] += add;
                        Console.WriteLine("    C 端数すべて同じ max>=0 minindex数+add add:"+add);
                        }
                        Console.WriteLine("    -> 移動後：" + string.Join(" , ", result_hasu));
                        // 端数を結果に試し計上
                        var t3 = result.Zip(result_hasu, (t1, t2) => Math.Round(t1 + Math.Round(t2, 1, MidpointRounding.AwayFromZero), 1, MidpointRounding.AwayFromZero)).ToList();
                        Console.WriteLine("    端数を試し計上：" + string.Join(" , ", t3) + " sum=" + t3.Sum());
                        if (t3.Sum() == 100)
                        {
                            break;
                        }
                    }
                    else
                    {
                        Console.WriteLine("    ★D★");
                        break;
                    }
                }
                loop_i++;
            } while (true);
            // 端数を結果に戻す
            result = result.Zip(result_hasu, (t1, t2) => Math.Round( t1 + Math.Round(t2, 1, MidpointRounding.AwayFromZero), 1, MidpointRounding.AwayFromZero)).ToList();
            return result;
        }
```