Как я могу сделать java.text.NumberFormat в формате 0.0d как «0», а не «+0»? - PullRequest
2 голосов
/ 23 марта 2009

Нужен результат со знаком, кроме 0.0d. То есть:

 -123.45d -> "-123.45",
  123.45d -> "+123.45",
  0.0d    -> "0".

Я вызываю format.setPositivePrefix("+") в экземпляре DecimalFormat для принудительного ввода знака в результате для положительных входных данных.

Ответы [ 4 ]

2 голосов
/ 23 марта 2009

Я уверен, что есть более элегантный способ, но посмотрите, работает ли он?

import static org.junit.Assert.assertEquals;

import java.text.ChoiceFormat;
import java.text.DecimalFormat;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParsePosition;

import org.junit.Test;

public class NumberFormatTest {
    @Test
    public void testNumberFormat() {
        NumberFormat nf = new MyNumberFormat();
        assertEquals("-1234.4", nf.format(-1234.4));
        assertEquals("0.0", nf.format(0));
        assertEquals("+0.3", nf.format(0.3));
        assertEquals("+12.0", nf.format(12));
    }
}

class MyNumberFormat extends NumberFormat {

    private DecimalFormat df = new DecimalFormat("0.0#");
    private ChoiceFormat cf = new ChoiceFormat(new double[] { 0.0,
            ChoiceFormat.nextDouble(0.0) }, new String[] { "", "+" });

    @Override
    public StringBuffer format(double number, StringBuffer toAppendTo,
            FieldPosition pos) {
        return toAppendTo.append(cf.format(number)).append(df.format(number));
    }

    @Override
    public StringBuffer format(long number, StringBuffer toAppendTo,
            FieldPosition pos) {
        return toAppendTo.append(cf.format(number)).append(df.format(number));
    }

    @Override
    public Number parse(String source, ParsePosition parsePosition) {
        throw new UnsupportedOperationException();
    }
}

Согласно Десятичный формат

Отрицательный подшаблон необязательный; если отсутствует, то положительный подшаблон с префиксом локализованного знака минус ('-' в большинстве локалей) используется как отрицательный подшаблон

Следовательно new DecimalFormat("0.0#") эквивалентно new DecimalFormat("0.0#;-0.0#")

Так что это даст нам: -1234.5 и 1234.5

Теперь, чтобы добавить '+' к положительным числам, я использую ChoiceFormat

  • 0.0 <= X < ChoiceFormat.nextDouble(0.0) будет использовать формат выбора "". ChoiceFormat.nextDouble(0.0) - наименьшее число, большее 0.0.
  • ChoiceFormat.nextDouble(0.0) <= X < 1 будет использовать формат выбора "+".

Если совпадений нет, то используется либо первый, либо последний индекс, в зависимости от того, слишком мало или слишком велико число (X). Если массив пределов находится не в порядке возрастания, результаты форматирования будут неверными. ChoiceFormat также принимает \ u221E как эквивалент бесконечности (INF).

Следовательно

  • Double.NEGATIVE_INFINITY <= X < 0 будет использовать "".
  • 1 <= X < Double.POSITIVE_INFINITY будет использовать "+".
1 голос
/ 24 марта 2009

Большое спасибо, ребята, некоторые очень хорошие идеи здесь.

Исходя из того, что было предложено, я решил использовать два формата: zeroFormat для специального случая для 0.0d и nonZeroFormat для остальных случаев. Я скрываю реализацию за IDisplayableValueFormatter (который используется пользовательским элементом управления пользовательским интерфейсом) и мне не нужно соблюдать контракт / интерфейс NumberFormat.

0 голосов
/ 19 октября 2011

Я только что столкнулся с этим в проекте, и я не нашел ни одного из ответов здесь особенно удовлетворительным.

Вместо этого я смог (что может работать, а может и не работать):

// Convert negative zero to positive zero.  Even though this
// looks like it should be a no-op, it isn't.
double correctedValue = (value == 0.0 ? 0.0 : value);

Тогда значение будет правильно отформатировано классом DecimalFormat.

Я на самом деле немного удивлен, что в Java нет встроенной подобной конструкции.

0 голосов
/ 23 марта 2009

Java имеет как «отрицательный ноль», так и «положительный ноль». Они имеют разные представления, но сравниваются как равные друг другу.

Если у вас должен быть знак плюс перед положительными значениями, но вы не хотите его использовать для положительного нуля, то вам может потребоваться сделать что-то подобное для временной очистки префикса:

try {
    if (val == 0.0) {
        format.setPositivePrefix("");
    }
    result = format.format(val);
}
finally {
    format.setPositivePrefix("+");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...