As always, the finger-made Android-Java, stumped out of the blue. What methods I did not try, what prayers and what saints I didn’t say, but I can’t solve an elementary task:

there is a long X1, X2 ... XN (time in milliseconds); there is their sum: X_sum.

How to get the values ​​of Y1, Y2 ... YN, where Yi = Xi / X_sum,

at the same time, the Yi format is 23.4%, and the sum of all Yi would be 100.0%, and not plus / minus a few percent, and the greater the number of Yi, the further the result from 100.0%. Rounding up the rules, as we were taught in school.

  • Look at: https://habrahabr.ru/post/219595/ In which type store the result (Yi = Xi / X)? - Igor
  • type is unimportant, just to be correct. Output to string. - St-st
  • I prayed to Saint BigDecimal, and read, and used the method proposed here: Android, feints with ears http://dolbodub.blogspot.com/2014/04/java.html . While unanswered. - St-St
  • I get a loss of accuracy of 10 ^ (- 14) .Te. The sum for 100 values ​​(the result of the division is stored in double) is 99.999999999999987, but do you need 100? - Igor
  • The problem here is not exactly. And in the wrong rounding. A rounding error on each value leads to a loss of 0.1%. It will be stupid if the user looks at a screen with 2 values, and their percentage reduction results in total 99.9%. And on 7 values ​​already 99.6%. "You can't count normally," the user mentally will pray to the developer. - St-st

2 answers 2

For your occasion it is enough to use

 double number = 0.1886717436742374; //1й вариант округления: double number1 = Math.rint(100.0 * d) / 100.0; //2й вариант: double number2 = BigDecimal.valueOf(number).setScale(2,BigDecimal.ROUND_HALF_DOWN).doubleValue(); 

And an example with the 2nd option:

 //Задаю количество элементов int numberOfElements = 16; //Массив для хранения long значений long[] longsArray = new long[numberOfElements]; long sum = 0; //Сумма long значений for (int i = 0; i < numberOfElements; i++) { longsArray[i] = System.currentTimeMillis(); //массив забиваю текущим временем System.out.println("i = " + i + "; longArray[i] = " + longsArray[i]); sum = sum + longsArray[i]; } System.out.println("sum of all X is = " + sum); //Массив для хранения Xi/Yi значений double[] yArray = new double[numberOfElements]; double sumOfY = 0; // Сумма всех Xi/Yi for (int i = 0; i < numberOfElements; i++) { yArray[i] = (double) 100 * longsArray[i] / sum; yArray[i] = BigDecimal.valueOf(yArray[i]).setScale(2, BigDecimal.ROUND_HALF_DOWN).doubleValue(); System.out.println("i = " + i + "; yArray[i] = " + yArray[i]); sumOfY = sumOfY + yArray[i]; } System.out.println("sum of Y is = " + sumOfY); 
  • Bravo! This is what you need: an error within the unit of the last character. Only in my case, it is necessary in the first parameter setScale (2, BigDecimal.ROUND_HALF_DOWN) to specify one, and not two. Thank you all. - St-St

As I understand it, all X s and X sum is of type long

try this

 double yi = ((Xi*1000) / X_summa) / 10. ; // 1000 для округления до 0,1 процента 

@ st-st

You need to store and summarize numbers as they are in a long format 0.098234235435

but you can display by rounding to 0.01

just the amount will be taken from the first option. no other way.

  • Your proposal gives a value in the form 91.9464688765 ...%. How to round up to 1 digit after a point correctly? :) - St-St
  • @ St-st try this option double yi = ((Xi*1000) / X_summa) / 10. ; at the end of the dozens point - Saidolim
  • This is closer: the format is correct, but the sum of all Yi starts from 99.9% and with an increase in the number of Yi their sum decreases: at 7 Yi, their sum is already 99.6% - St-st
  • @ St-st is correct, because we are cutting off part after comma. you will never have the amount to go. It will still be rounding. You can collect this garbage in the last elements. if so necessary. - Saidolim
  • Dear members of the forum, just let's not say that this is correct. Algebra, we were taught in school, invented by the Arabs, and it is the measure of truth. Android god would need to finish high school, and then shovel the billions with a shovel. To dump the inaccuracy of the calculations into some elements is already very close with the censing near the painted boards. And why are there no such problems in the products that Myrosoft criticizes? Especially in Excel, I made a sign for 20 values ​​- the error is all 0.1%. - St-St