Нечетный результат округления до десятичного числа на половину

Предоставление значения с плавающей запятой 37.35 Я получаю строку 37.3

Вот мой код

DecimalFormat format = new DecimalFormat(".0");
format.setRoundingMode(RoundingMode.HALF_UP);
return format.format(37.35f);

Я ожидал бы получить строку 37.4, Что я делаю неправильно?

Я думаю, что это может быть связано с передачей числа с плавающей запятой, однако у меня нет выбора относительно типа переменной, которую я получаю. Даже если фактическое представление float было 37.3500221215051544 это все еще должно быть округлено?

Весь смысл форматирования этого значения в строку, чтобы я мог передать его BigDecimal и имеют точные значения, такие как 37.4,

2 ответа

Решение

37,35 фактически ближе к 37,3, а затем к 37,4. Вы можете проверить это с помощью следующего кода:

System.out.println(37.35f-37.3f);
System.out.println(37.4f-37.35f);

в принтах 0.049999237 а также 0.05000305,

С double Тип данных результат отличается.

Чтобы решить эту проблему, просто добавьте небольшую дельту к своим номерам. Например, 0,01.

Эта проблема связана с точностью типа данных float в арифметике с плавающей точкой компьютера. Как показывает @Zefick в своем ответе, представление числа с плавающей точкой 37,35 на самом деле ближе к 37,3, чем к 37,4; потому что это немного меньше, чем 37,35.

Использование двойной точности решает проблему, но, поскольку это ограничение, я предлагаю использовать оболочку:

    return format.format(Double.valueOf(String.valueOf(37.35f)));
Другие вопросы по тегам