O que eu gostaria é de um método para converter um duplo para uma string que arredonda usando o método halff-up - ou seja, se o decimal a ser arredondado for 5, ele sempre arredonda para o próximo número. Este é o método padrão de arredondamento que a maioria das pessoas espera na maioria das situações.
Eu também gostaria que apenas dígitos significativos fossem exibidos - ou seja, não deve haver zeros traiçoeiros.
Eu sei que um método para fazer isso é utilizar o método `String.format':
String.format("%.5g%n", 0.912385);
regressa:
0.91239
o que é ótimo, porém sempre exibe números com 5 casas decimais, mesmo que não sejam significativos:
String.format("%.5g%n", 0.912300);
regressa:
0.91230
Outro método é utilizar a 'DecimalFormatter':
DecimalFormat df = new DecimalFormat("#.#####");
df.format(0.912385);
regressa:
0.91238
No entanto, como você pode ver, isso usa arredondamento de meia-entrada. Isto é, ele irá arredondar para baixo se o dígito anterior for igual. O que I'gostaria é isto:
0.912385 -> 0.91239
0.912300 -> 0.9123
Qual é a melhor maneira de conseguir isso em Java?
Utilize setRoundingMode`, defina o RoundingMode
explicitamente para lidar com o seu problema com a meia-volta, depois utilize o padrão de formato para a sua saída desejada.
Exemplo:
DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
Double d = n.doubleValue();
System.out.println(df.format(d));
}
dá a saída:
12
123.1235
0.23
0.1
2341234.2125
**EDIT***: A resposta original não aborda a precisão dos valores duplos. Isso é bom se você não se importa muito se ele arredonda para cima ou para baixo. Mas se você quiser arredondamentos precisos, então você precisa levar em conta a precisão esperada dos valores. Os valores em pontos flutuantes têm uma representação binária internamente. Isso significa que um valor como 2,77395 não tem, na verdade, esse valor exato internamente. Ele pode ser ligeiramente maior ou ligeiramente menor. Se o valor interno for ligeiramente menor, então ele não irá arredondar para 2,7740. Para remediar essa situação, você precisa estar ciente da precisão dos valores com os quais está trabalhando, e adicionar ou subtrair esse valor antes de arredondar. Por exemplo, quando você sabe que seus valores são precisos até 6 dígitos, então para arredondar valores de meio caminho para cima, adicione essa precisão ao valor:
Double d = n.doubleValue() + 1e-6;
Para arredondar para baixo, subtraia a precisão.