Domanda

Sto cercando di prendere due numeri di 7 cifre (conteggi record di origine e destinazione) e calcolare la percentuale di record mancanti nel conteggio obiettivo.

Ad esempio, i miei conteggi dei record potrebbero essere 4084094 per l'origine e 4081313 per l'obiettivo. Sto anche usando la seguente formula per calcolare la percentuale: ((1 - (target / source)) * 100)

Per il mio esempio, dovrei ottenere il valore di circa 0,0681%

Sono nuovo di Java e JSP e non riesco a visualizzare correttamente la percentuale. Mi sembra di ottenere solo un valore arrotondato per difetto a 0.

Ho anche provato BigDecimal, inutilmente.

Anche il seguente semplice codice mostra il valore di 1-1, quindi ovviamente sto facendo qualcosa di gravemente sbagliato:

<%
BigDecimal percentMiss;
long tmp = 600/500;
percentMiss = BigDecimal.valueOf(tmp);
%>
<%=percentMiss.toString()%>-<%=tmp%>
È stato utile?

Soluzione

Il problema è nella seguente riga

long tmp = 600/500;

Non puoi memorizzare numeri in virgola mobile in un lungo, invece dovresti considerare di usare il seguente codice:

double tmp = (double)600 / (double)500;

e quindi visualizzare tmp, che dovrebbe avere un valore compreso tra 0 e 1 (nel tuo caso 1.2, perché devi modificare il tuo calcolo in 500/600)

Altri suggerimenti

Il problema è ovviamente che stai dividendo due numeri lunghi.

Consiglierei di usare DecimalFormat per visualizzare il numero. Se si utilizza JSTL, una soluzione ancora migliore consiste nell'utilizzare tag di formato :

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<fmt:formatNumber value="${value}" minFractionDigits="2" maxFractionDigits="2"/>

Il tuo problema è che 600 e 500 sono valori interi e una divisione tra loro avrà un risultato intero, che assegni a un intero lungo. Successivamente, la parte frazionaria del risultato è sparita (due volte) e non è possibile recuperarla.

Per ottenere un risultato frazionario, almeno uno dei valori di input della divisione deve essere non intero. Puoi farlo lanciandoli in double o float , oppure facendo esplicitamente raddoppiare o fluttuare i letterali in questo modo:

500.0 // implicitly double
500f // float literal
500d // double literal

Tuttavia, la stampa del risultato di un doppio / float divison avrà spesso più decimali di quanto si desideri anche se non dovrebbero essere nel risultato (es. 1/10 può risultare in 0.100000001490116119384765625 ), a causa di il modo in cui questi numeri sono memorizzati come frazioni binarie .

Puoi eliminare queste cifre indesiderate usando java.lang.DecimalFormat , ma BigDecimal è un'opzione migliore, poiché utilizza internamente le frazioni decimali e quindi fornirà effettivamente risultati corretti offrendo al contempo il controllo esatto sulle modalità di arrotondamento. Naturalmente, questo richiede di utilizzare BigDecimal per il calcolo stesso, piuttosto che come "ingrediente voodoo". per correggere un risultato già interrotto.

new BigDecimal(600).divide(new BigDecimal(500))

Leggi la documentazione API per BigDecimal per ulteriori informazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top