Як я можу скоротити двійник лише до двох знаків після коми в Java?


93

Наприклад, у мене є змінна 3,545555555, яку я хотів би скоротити лише до 3,54.


18
Це НЕ дублікат. Зрізання та округлення - це дві абсолютно різні речі.
markthegrea

Погоджено, не знаю, чому це позначено як дублікат.
Bassinator

Відповіді:


144

Якщо ви хочете це зробити для демонстрації, використовуйте java.text.DecimalFormat:

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

Якщо вам це потрібно для розрахунків, використовуйте java.lang.Math:

 Math.floor(value * 100) / 100;

50
Це не відображатиме усічені 3,545555555 до 3,54, але округлені до 3,55. DecimalFormat.setRoundingMode () потрібно встановити RoundingMode.FLOOR;
Крістіан Гарсія

9
це не працює для мене Math.floor (9.62 * 100) / 100 дає 9.61
Mani

4
Використання floorдля обрізання працює лише для позитивних значень.
Dev

3
@ ChristianGarcía Зрізання зроблено належним чином, RoundingMode.DOWNяк RoudingMode.FLOORзавжди кружляє до негативної нескінченності.
Dev

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

Перевірте наявність RoundingModeі DecimalFormat.


Не стосується Питання, яке вимагало скорочення, а не округлення.
Василь Бурк,

8
@BasilBourque RoundingMode.DOWN - це усічення. Порівняйте з іншими відповідями, які неправильно рекомендують функції підлоги (підлога усічує лише позитивні числа), це правильно працює як для позитивних, так і для негативних значень.
Dev

1
@Dev Я стою виправлений. Зараз я бачу, що DOWNнасправді має ефект усічення як для позитивних, так і для негативних чисел. Як видно з таблиці прикладів у документі .
Василь Бурк

23

Трохи старий форум, жодна з наведених відповідей не працювала як для позитивних, так і для негативних значень (я маю на увазі для обчислення і просто для обрізання без округлення). З Хау округлити число до п знаків після коми в 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);
    }
}

Цей метод у мене спрацював добре.

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));

Результати:

0.00
9.62
9.62
9.62
9.62
9.99
-9.99
-9.00

це відповідь, яка може бути масштабована для більшої кількості тестових випадків
Дієго Матос - Кеке

повернути новий BigDecimal (x) .setScale (numberofDecimals, RoundingMode.DOWN) .doubleValue ();
Шимон Дудкін

здається, округлий вниз - це те, що ви мали на увазі: docs.oracle.com/javase/7/docs/api/java/math/RoundingMode.html
Шимон Дудкін

9

Спочатку зауважимо, що a doubleє двійковим дробом і насправді не має десяткових знаків.

Якщо вам потрібні десяткові знаки, використовуйте a BigDecimal, який має setScale()метод усічення, або використовуйте, DecimalFormatщоб отримати a String.


7

Якщо з якихось причин ви не хочете використовувати a, BigDecimalви можете doubleпередати його на, intщоб усічити його.

Якщо ви хочете скоротити місце до Онесів :

  • просто кинути int

До десятих місць:

  • помножте на десять
  • кинути до int
  • відкинути назад до double
  • і ділити на десять.

Місце хандретів

  • помножте і поділіть на 100 тощо.

Приклад:

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;
}

У цьому прикладі, decimalPlacesбуло б число місць ПОВЗ то місце , куди ви хочете поїхати, тому 1 буде округлення до десятих місця, 2 до сотих , і так далі (0 раундів на тих , місця і негативною до десятків тощо)


3
Це жахливе загальне рішення. Як множення, так і бросок в кінцевому підсумку викидають дані і в результаті отримують фактично випадкові числа, якщо unroundedNumberвони досить великі. Це може працювати для прикладу у питанні, але загальне рішення має працювати для будь-якого double.
blm

4

Форматування як рядок і перетворення назад у подвійне, я думаю, це дасть вам результат, який ви хочете.

Подвійне значення не буде круглим (), підлоговим () або стельовим ().

Швидким виправленням цього може бути:

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

Ви можете використовувати sValue для відображення або newValue для розрахунку.


1
Це робить округлення для мене до найближчого значення. Наприклад, 0,018 перетворюється на 0,02, коли я це робив.
karan patel

3

Може бути Math.floor(value * 100) / 100? Зверніть увагу, що значення типу 3.54можуть бути не точно представлені символом double.


3

Ви можете використовувати об’єкт ClassFormat Class для виконання завдання.

// 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, щоб отримати 3,54. Спробуйте дотримуватися цього:

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

    df.setRoundingMode(RoundingMode.FLOOR);

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

Це дасть = 3,54!


1

Ось метод, який я використовую:

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

Це також можна зробити:

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

0

Можливо, наступне:

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

Дивіться інші відповіді. Ви не можете зробити це надійно, якщо відповідь буде представлена ​​з плаваючою комою.
Маркіз Лорнський,

0

Швидка перевірка полягає у використанні методу Math.floor. Я створив метод перевірки подвійного на два або менше десяткових знаків нижче:

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

У мене є трохи модифікована версія Мані .

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));

}

Вихід:

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

Це працювало для мене:

double input = 104.8695412  //For example

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

//result == 104.87

Мені особисто подобається ця версія, оскільки вона насправді виконує округлення чисельно, а не перетворюючи її на Рядок (або подібну), а потім форматуючи.


1
Початкове питання стосується усічення, а не округлення. Крім того, перетворення подвійного на довгий взагалі не буде добре працювати, якщо подвійне досить велике.
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

ну це може бути трохи незручно, але я думаю, що це може вирішити вашу проблему :)


Цей код робить роботу, але він не елегантний і погано працює. Це може бути нормально у шкільних проектах, але точно не рішення, яке хтось би використовував у виробництві для будь-якої системи, якщо тільки ви не хочете пізніше боліти в голові.
cbaldan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.