обнаружение округления с плавающей запятой

Я использую java и имею в виду «двойной» тип данных. Короче говоря, я читаю некоторые значения из стандартного ввода, которые я читаю в своем коде как двойные (я бы предпочел использовать что-то вроде BigInteger, но сейчас это невозможно).

Я ожидаю получить двойные значения от пользователя, но иногда они могут вводить такие вещи, как: 9999999999999999999999999999.9999999999, что, я думаю, выходит за рамки точного представления для двойного числа и округляется до 1.0E27 (вероятно).

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

Большое спасибо


person cupu    schedule 06.11.2008    source источник


Ответы (3)


Большинство значений, введенных людьми, не будут точно представлены с помощью двойника.

Например, вы хотите запретить пользователю вводить 0,1? Это не совсем то, что можно представить как двойное.

Чтобы найти масштаб ошибки, вы можете сделать что-то вроде:

BigDecimal userAsDecimal = new BigDecimal(userInput);
double userAsDouble = double.parseDouble(userInput);
BigDecimal doubleToDecimal = new BigDecimal(userAsDouble);
BigDecimal error = userAsDecimal.subtract(userAsDouble).abs();

Затем проверьте, является ли «ошибка» допустимо малой.

person Jon Skeet    schedule 06.11.2008
comment
Ведь вы правы. Чтобы быть более конкретным, я всегда буду получать положительные числа с точностью не более 10 цифр, поэтому мое требование состояло бы в том, чтобы ограничить всю часть числа, чтобы это не вызывало округления. - person cupu; 06.11.2008
comment
Боюсь, я все еще не совсем понимаю. Вы имеете в виду, что на самом деле вы получите только целые числа? Если это так, используйте длинный. Если нет, то я снова пропал... - person Jon Skeet; 06.11.2008
comment
У меня возникла небольшая проблема с формулировкой запроса. Спасибо (особенно) и всем остальным, кто ответил, в моем случае использовать double действительно плохо ... на что я некоторое время жаловался :). - person cupu; 06.11.2008

Вы не можете использовать двойник для хранения чего-то точно так, как вы спрашиваете, очень редко пользователь может ввести число, которое может идеально представлять двойник, но это будет только совпадение. Если вам нужно сохранить точное число, вы можете использовать строку, если вам не нужно выполнять какие-либо манипуляции. Если вам нужно больше, то, вероятно, есть библиотеки, созданные для такой точной математики.

person tloach    schedule 06.11.2008

person    schedule
comment
Спасибо за фрагмент .. это удобный тест и, так сказать, хороший опыт для меня. Я не буду его использовать, вероятно, потому что я устраню бесконечные значения ... но это моя проблема :). Спасибо еще раз - person cupu; 06.11.2008