c# - Rounding by adding or subtracting 1 unit to the highest or lowest value item in list until row totals 100 -
i have pre populated datatable, each row in datatable needs add together 100
i'm trying utilize approach if total value of row less 100, loop through values in row , add together 1 unit largest value first, check if 100 reached, if not add together 1 unit sec largest value in row , on.
example:
original data
50.2, 40.6, 9.0 total 99.8
after rounding:
50.3, 40.7, 9.0 total 100.0
if overall total value row more 100 wish repeat process removing 1 unit largest value first etc...
i have nail number of stumbling blocks, first sorting datatable proved problem don't know column names etc converted array.
the main problem can't perform final adjustment in line (int = 0; < temadj; a++) temadj 0 then.
private datatable roundingandscaling(datatable dtinput, int startingcol, int decplaces = 1) { int dtrows = dtinput.rows.count; int dtcols = dtinput.columns.count; double temadj; double temprowtotal; int tempsig; datatable dtouput = new datatable(); dtouput = dtinput.copy(); datatable dtfinal = new datatable(); dtfinal = dtinput.copy(); double[,] outputarray = new double[dtouput.columns.count, 2]; (int r = 0; r < dtrows - 1; r++) { temprowtotal = 0; (int c = startingcol; c < dtcols; c++) { if (dtinput.rows[r][c] == dbnull.value) { dtouput.rows[r][c] = 0.0; } else { dtouput.rows[r][c] = math.round((double)dtinput.rows[r][c], decplaces); } outputarray[c - startingcol, 0] = convert.todouble(dtouput.rows[r][c]); temprowtotal = temprowtotal + convert.todouble(dtouput.rows[r][c]); } //now check if cells in row = 100 if (temprowtotal != 100) { tempsig = 1; //sort info double[,] arraydb = new double[dtouput.columns.count, 2]; arraydb = sortarray(outputarray, dtcols); //find how many assets need adjusted 1 unit temadj = (temprowtotal - 1) * (10 ^ decplaces); //10^ if (temadj < 0) { temadj = -1 * temadj; tempsig = -1; } //make adjustment assets have largest holdings (int = 0; < temadj; a++) { dtouput.rows[(int)(arraydb[dtcols, 1])][1] = (int)dtouput.rows[(int)(arraydb[dtcols, 1])][1] - tempsig * 1 / (10 ^ decplaces); //^10 } //get info right construction homecoming // (int xx = 0; xx < dtcols; xx++) // { // dtfinal.rows[dtrows][xx - 1] = dtouput.rows[xx][1]; // } } } homecoming dtouput; } private double [,] sortarray(double [,] indata, int templen) { double temval1; double temval2; (int = 0; < templen; i++) { (int j = + 1; j < templen; j++) { if (indata[i,0] > indata [j,0]) { temval1 = indata[i, 0]; temval2 = indata [i,1]; indata [i,0] = indata [j,0]; indata[i,1] = indata [j,1]; indata[j, 0] = temval1; indata[j, 1] = temval2; } } } homecoming indata; }
personally i'm not happy approach @ , sure there much simpler way accomplish trying do, i'll happily throw above out , go simpler approach :) help much appreciated.
list<decimal> numlist = new list<decimal>(); numlist.add(50.2m); numlist.add(40.6m); numlist.add(9.0m); decimal diff = 100.0m - numlist.sum(); //this set because value should 1 decimal place int update = convert.toint32(diff / .1m); if (update > 0) { (int x = 0; x < update; x++) { numlist[x % numlist.count()] += .1m; } } else { (int x = 0; x < math.abs(update); x++) { numlist[x % numlist.count()] -= .1m; } }
i used decimal improve precision, here illustration info take difference , seek have equal 100%. (i set in code if on 100% , want cutting downwards evenly well)
c# datatable number-rounding
No comments:
Post a Comment