Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9301

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

$
0
0
四捨五入率後割合百パーセント超え 下記のように、割合はすべて、16.666の場合、 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 /// <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; }

Viewing all articles
Browse latest Browse all 9301

Trending Articles