2015-01-06 11 views
0

Мне нужно округлить число до двух знаков после запятой:Округление числа до двух знаков после запятой в Java

1.1245 → 1.13 1.1235 → 1,12

Я провел последние два дня чистящими StackOverflow, и я был не в состоянии получить любое решение, которое я нашел, чтобы работать на всех:

Они все, кажется, просто обрезает номер на третьем знаке после запятой, а затем вокруг него оттуда, что не то, что я пытаюсь сделать. Я пытаюсь начать с места, расположенного дальше всего справа, а затем начать округлять соответственно; 5-9 идет вверх, 0-4 не влияет и отбрасывается.

Вот текущий код, я работаю с:

BigDecimal a = new BigDecimal("1.1245"); 
double b = Math.round(a.doubleValue() * 100)/100; 

System.out.print(a.setScale(2, BigDecimal.ROUND_HALF_EVEN) + " : " 
+ a.setScale(2, BigDecimal.ROUND_HALF_UP) + " : " 
+ b); 

А вот выход прямо из консоли:

console output

Проблема здесь в том, что я ожидаю 1.13 быть результатом во всех вышеуказанных случаях, как если бы выполнялся следующий процесс:

1.1245 → 1.125 → 1.13 
1.1235 → 1.124 → 1.12 
+5

Ваше правило округления довольно необычно – njzk2

+6

что вы говорите, что '1.1244 -> 1.12' и' 1.245 -> 1.13'? (никто этого не делает) – njzk2

+1

Зачем это было то, что вы хотите? '1.1245' _strictly_ ближе к 1.12, чем к 1.13. –

ответ

1

Я бы проверить расстояние со стандартным округлением, а затем настроить и круглый снова:

for (String string : new String[] {"1.1245", "1.1244", "1.1235", "1.1249", "1.1299"}) { 
     BigDecimal a = new BigDecimal(string); 

     if (a.setScale(2, BigDecimal.ROUND_HALF_UP).subtract(a).compareTo(new BigDecimal("-0.0044")) < 0) { 
      System.out.println(string + ":" + a.add(new BigDecimal("0.001")).setScale(2, BigDecimal.ROUND_HALF_UP)); 
     } else { 
      System.out.println(string + ":" + a.setScale(2, BigDecimal.ROUND_HALF_UP)); 
     } 
    } 

Результат:

1.1245:1.13 
1.1244:1.12 
1.1235:1.12 
1.1249:1.13 
1.1299:1.13 
+0

Я думаю, что кто-то, кому может просто удалять это сообщение, не позволяет ему запутать кого-либо еще. Также спасибо за ответ. Я просто собираюсь использовать ROUND_HALF_UP и называть его золотым. – nihilon

-1
public static double Rnd(double d) 
{ 
    d *= 100; 
    d += .5; 
    d = (int)d; 
    d /= 100; 
    return d; 
} 

Это самый лучший способ, которым я научился за округление, как два 100s может быть отрегулирован в тур по разным местам

+0

Я только что увидел часть вокруг закругления странным образом. Это не будет следовать этому правилу. Возможно, вам понадобится округлить до 1000, а затем 100 секунд, чтобы исправить эту проблему. –

+0

Эй, по крайней мере, я попробовал; Я не вижу, чтобы многие другие отправляли ответы –

1

Я думаю, вы должны дважды проверить спецификацию, поскольку требование является редкостью. Во всяком случае, я думаю, что это то, что вы (кажется, в) необходимость:

public BigDecimal round(BigDecimal n, int scale) { 
    if (n.scale() > scale) { 
     return round(n.setScale(n.scale() - 1, RoundingMode.HALF_UP), scale); 
    } else { 
     return n.setScale(scale, RoundingMode.UNNECESSARY); 
    } 
} 
+1

Я думаю, что OP ожидает 'round (" 1.124 ");' to give '1.12'. Предполагается, что только '1.1245' и выше должны дать 1.13 – njzk2

+0

Да, и я это понимаю сейчас. И почему это необычно. И в основном неправильно. К счастью, это была не спецификация. Это было мое неправильное понимание того, как работают округлые работы, поэтому я ожидал неправильного результата. – nihilon

+0

Я скорректировал свой ответ, чтобы удовлетворить требования OP. Эта функция рекурсивного округления должна называться как «round (new BigDecimal (« 1.1245 »), 2)' – Raffaele

Смежные вопросы