c# - sottrarre - il 10% di



Qual è il modo migliore per creare un valore percentuale da due numeri interi in C#? (6)

Ho due interi che voglio dividere per ottenere una percentuale.

Questo è quello che ho adesso:

int mappedItems = someList.Count(x => x.Value != null);
int totalItems = someList.Count();
(int)(((double)mappedItems /(double) totalItems) * 100)

Questo dà la risposta giusta. Ma questo è un sacco di casting per fare qualcosa di semplice come ottenere una percentuale tra due numeri.

C'è un modo migliore per farlo? Qualcosa che non coinvolga il casting?

https://src-bin.com


Answer #1

È possibile ottenere un risultato arrotondato correttamente utilizzando solo le operazioni integer:

int percent = (200 * mappedItems + 1) / (totalItems * 2);

Moltiplicando due, aggiungendo uno e dividendo per due, si sta effettivamente aggiungendo una metà. Questo rende la divisione intera un arrotondamento invece di troncare.


Answer #2

Bene, supponendo che i tuoi conteggi siano inferiori a int.MaxValue:

int percent = mappedItems * 100 / totalItems;

Answer #3

Giusto per aggiungere che come hai int e vuoi calcolare la percentuale (un valore in virgola mobile) devi fare il casting. Che sia esplicito come in C # o implicito come in alcuni linguaggi di scripting, il cast continuerà comunque. È meglio renderlo esplicito.

Se vuoi meno cast per riga di codice puoi scrivere:

double mappedItems = (double)someList.Count(x => x.Value != null);
double totalItems = (double)someList.Count();
double percentage = (mappedItems / totalItems) * 100.0);

Anche se come altri hanno sottolineato, controlla che gli totalItems siano 0 (preferibilmente prima di lanciare il doppio) per evitare una divisione per zero.


Answer #4

Il giusto modo intero per ottenere la percentuale con arrotondamenti appropriati è:

int result = ( mappedItems * 200 + totalItems ) / ( totalItems * 2 );

Come ci arriviamo? Se facciamo questa cosa in virgola mobile, sarebbe Math.Floor( mappedItems * 100.0 / totalItems + 0.5 ) . Abbiamo bisogno di trasformare questa formula in numero intero, moltiplicando e dividendo 0.5 per totalItems, quindi spostando 0.5 * totalItems in dividendo, e quindi moltiplicando dividendo e divisore per 2 per far sparire le frazioni:

mappedItems * 100.0 / totalItems + 0.5 => mappedItems * 100.0 / totalItems + totalItems * 0.5 / totalItems => (mappedItems * 100.0 + 0.5 * totalItems) / totalItems => (mappedItems * 200.0 + totalItems) / (totalItems * 2).

A questo punto la formula è solo per numeri interi. Quando eseguiamo la divisione intera, otteniamo un risultato floored, quindi il risultato solo-intero è equivalente a quello a virgola mobile citato.


Answer #5

Se volessi evitare i cast, potresti scrivere:

(100 * mappedItems) / totalItems

ma questo si mappedItems > int.MaxValue / 100 rapidamente quando mappedItems > int.MaxValue / 100 .

E entrambi i metodi arrotondano la percentuale verso il basso. Per ottenere l'arrotondamento corretto, terrei il risultato come un doppio:

((double)mappedItems /(double) totalItems) * 100

Answer #6

prova questo:

int mappedItems = someList.Count(x => x.Value != null);
int totalItems = someList.Count();
int percent = Convert.ToInt32(complete * 100.0 / total);

in questo esempio, il risultato sarà "50"

int mappedItems = 14;
int totalItems = 28;
int result = Convert.ToInt32(mappedItems * 100.0 / totalItems);
// result is 50




casting