Come posso troncare un doppio a solo due cifre decimali in Java?


93

Ad esempio, ho la variabile 3.545555555, che vorrei troncare a soli 3.54.


18
Questo NON è un duplicato. Il troncamento e l'arrotondamento sono due cose completamente diverse.
markthegrea

D'accordo, non so perché questo è contrassegnato come duplicato.
Bassinator

Risposte:


144

Se lo desideri per scopi di visualizzazione, usa java.text.DecimalFormat:

 new DecimalFormat("#.##").format(dblVar);

Se ne hai bisogno per i calcoli, usa java.lang.Math:

 Math.floor(value * 100) / 100;

50
Questo non visualizzerà un 3.545555555 troncato a 3.54, ma arrotondato a 3.55. DecimalFormat.setRoundingMode () deve essere impostato su RoundingMode.FLOOR;
Christian García

9
questo non funziona per me Math.floor (9.62 * 100) / 100 dà 9.61
Mani

4
L'utilizzo floordi troncare funziona solo per valori positivi.
Dev

3
@ ChristianGarcía Il troncamento viene eseguito correttamente con RoundingMode.DOWNcome RoudingMode.FLOORsempre arrotondamenti verso l'infinito negativo.
Dev

46
DecimalFormat df = new DecimalFormat(fmt);
df.setRoundingMode(RoundingMode.DOWN);
s = df.format(d);

Verifica disponibile RoundingModee DecimalFormat.


Non affronta la domanda, che richiedeva il troncamento anziché l'arrotondamento.
Basil Bourque

8
@BasilBourque RoundingMode.DOWN è il troncamento. Confronta con altre risposte che raccomandano erroneamente le funzioni del pavimento (il pavimento tronca solo i numeri positivi), funziona correttamente sia per i valori positivi che per quelli negativi.
Dev

1
@ Dev mi trovo corretto. Vedo ora che DOWNha effettivamente l'effetto di troncamento sia per i numeri positivi che per quelli negativi. Come si vede nella tabella degli esempi nel doc .
Basil Bourque

23

Bit Old Forum, nessuna delle risposte precedenti ha funzionato sia per valori positivi che negativi (intendo per il calcolo e solo per troncare senza arrotondamento). Dal collegamento Come arrotondare un numero an decimale in Java

private static BigDecimal truncateDecimal(double x,int numberofDecimals)
{
    if ( x > 0) {
        return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_FLOOR);
    } else {
        return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_CEILING);
    }
}

Questo metodo ha funzionato bene per me.

System.out.println(truncateDecimal(0, 2));
    System.out.println(truncateDecimal(9.62, 2));
    System.out.println(truncateDecimal(9.621, 2));
    System.out.println(truncateDecimal(9.629, 2));
    System.out.println(truncateDecimal(9.625, 2));
    System.out.println(truncateDecimal(9.999, 2));
    System.out.println(truncateDecimal(-9.999, 2));
    System.out.println(truncateDecimal(-9.0, 2));

Risultati:

0.00
9.62
9.62
9.62
9.62
9.99
-9.99
-9.00

questa è la risposta più scalabile per più test case
diego matos - keke

restituisce new BigDecimal (x) .setScale (numberofDecimals, RoundingMode.DOWN) .doubleValue ();
Shimon Doodkin

sembra arrotondato per difetto
Shimon Doodkin

9

Nota prima che una doubleè una frazione binaria e in realtà non hanno cifre decimali.

Se hai bisogno di posizioni decimali, usa a BigDecimal, che ha un setScale()metodo per il troncamento, o usa DecimalFormatper ottenere a String.


7

Se, per qualsiasi motivo, non vuoi usare a BigDecimal, puoi lanciarlo doublein an intper troncarlo.

Se vuoi troncare al posto Ones :

  • trasmetti semplicemente a int

Al decimo posto:

  • moltiplicare per dieci
  • cast a int
  • ricondotto a double
  • e dividi per dieci.

Centinaia di posti

  • moltiplicare e dividere per 100 ecc.

Esempio:

static double truncateTo( double unroundedNumber, int decimalPlaces ){
    int truncatedNumberInt = (int)( unroundedNumber * Math.pow( 10, decimalPlaces ) );
    double truncatedNumber = (double)( truncatedNumberInt / Math.pow( 10, decimalPlaces ) );
    return truncatedNumber;
}

In questo esempio, decimalPlacessarebbe il numero di posti PASSATO quelli luogo che si desidera andare, in modo da 1 sarebbe intorno al decimo posto, 2 ai centesimi , e così via (0 giri al quelle posto, e uno negativo per le decine , eccetera.)


3
Questa è una terribile soluzione generale. Sia il moltiplicatore che il cast finiranno per buttare via i dati e dare origine a numeri effettivamente casuali se unroundedNumbersono abbastanza grandi. Potrebbe funzionare per l'esempio nella domanda, ma una soluzione generale dovrebbe funzionare per qualsiasi double.
blm

4

Formattare come una stringa e riconvertire in doppio penso che ti darà il risultato che desideri.

Il valore double non sarà round (), floor () o ceil ().

Una soluzione rapida potrebbe essere:

 String sValue = (String) String.format("%.2f", oldValue);
 Double newValue = Double.parseDouble(sValue);

È possibile utilizzare sValue per scopi di visualizzazione o newValue per il calcolo.


1
Per me viene arrotondato al valore più vicino. Ad esempio: 0,018 viene convertito in 0,02 quando l'ho fatto.
karan patel

3

Forse Math.floor(value * 100) / 100? Attenzione che i valori come 3.54potrebbero non essere esattamente rappresentati con un double.


3

È possibile utilizzare l'oggetto NumberFormat Class per eseguire l'attività.

// Creating number format object to set 2 places after decimal point
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(2);            
nf.setGroupingUsed(false);

System.out.println(nf.format(precision));// Assuming precision is a double type variable

3

3.545555555 per ottenere 3.54. Prova a seguire per questo:

    DecimalFormat df = new DecimalFormat("#.##");

    df.setRoundingMode(RoundingMode.FLOOR);

    double result = new Double(df.format(3.545555555);

Questo darà = 3.54!


1

Ecco il metodo che utilizzo:

double a=3.545555555; // just assigning your decimal to a variable
a=a*100;              // this sets a to 354.555555
a=Math.floor(a);      // this sets a to 354
a=a/100;              // this sets a to 3.54 and thus removing all your 5's

Questo può essere fatto anche:

a=Math.floor(a*100) / 100;

0

Forse seguendo:

double roundTwoDecimals(double d) { 
      DecimalFormat twoDForm = new DecimalFormat("#.##"); 
      return Double.valueOf(twoDForm.format(d));
}  

Vedi le altre risposte. Non puoi farlo in modo affidabile se la risposta deve essere rappresentata in virgola mobile.
Marchese di Lorne

0

Un rapido controllo consiste nell'usare il metodo Math.floor. Ho creato un metodo per controllare un doppio per due o meno cifre decimali di seguito:

public boolean checkTwoDecimalPlaces(double valueToCheck) {

    // Get two decimal value of input valueToCheck 
    double twoDecimalValue = Math.floor(valueToCheck * 100) / 100;

    // Return true if the twoDecimalValue is the same as valueToCheck else return false
    return twoDecimalValue == valueToCheck;
}

-1

Ho una versione leggermente modificata di Mani .

private static BigDecimal truncateDecimal(final double x, final int numberofDecimals) {
    return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_DOWN);
}

public static void main(String[] args) {
    System.out.println(truncateDecimal(0, 2));
    System.out.println(truncateDecimal(9.62, 2));
    System.out.println(truncateDecimal(9.621, 2));
    System.out.println(truncateDecimal(9.629, 2));
    System.out.println(truncateDecimal(9.625, 2));
    System.out.println(truncateDecimal(9.999, 2));
    System.out.println(truncateDecimal(3.545555555, 2));

    System.out.println(truncateDecimal(9.0, 2));
    System.out.println(truncateDecimal(-9.62, 2));
    System.out.println(truncateDecimal(-9.621, 2));
    System.out.println(truncateDecimal(-9.629, 2));
    System.out.println(truncateDecimal(-9.625, 2));
    System.out.println(truncateDecimal(-9.999, 2));
    System.out.println(truncateDecimal(-9.0, 2));
    System.out.println(truncateDecimal(-3.545555555, 2));

}

Produzione:

0.00
9.62
9.62
9.62
9.62
9.99
9.00
3.54
-9.62
-9.62
-9.62
-9.62
-9.99
-9.00
-3.54

-2

Questo ha funzionato per me:

double input = 104.8695412  //For example

long roundedInt = Math.round(input * 100);
double result = (double) roundedInt/100;

//result == 104.87

Personalmente mi piace questa versione perché esegue effettivamente l'arrotondamento numericamente, anziché convertirlo in una stringa (o simile) e quindi formattarlo.


1
La domanda originale riguarda il troncamento, non l'arrotondamento. Inoltre, convertire un doppio in un lungo non funzionerà affatto bene se il doppio è abbastanza grande.
blm

-2
//if double_v is 3.545555555
String string_v= String.valueOf(double_v);
int pointer_pos = average.indexOf('.');//we find the position of '.'
string_v.substring(0, pointer_pos+2));// in this way we get the double with only 2 decimal in string form
double_v = Double.valueOf(string_v);//well this is the final result

beh questo potrebbe essere un po 'imbarazzante, ma penso che possa risolvere il tuo problema :)


Questo codice esegue il lavoro, ma non è elegante e ha prestazioni scadenti. Potrebbe andare bene nei progetti scolastici, ma sicuramente non è una soluzione che qualcuno userebbe in produzione per qualsiasi sistema, a meno che tu non voglia avere mal di testa in seguito.
cbaldan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.