Надежная картана Яве - PullRequest
       3

Надежная картана Яве

2 голосов
/ 02 января 2012

Я ищу надежную Карту на Java, где поиск ключа учитывал бы, что Double имеет ограниченную точность (что-то около 1e-15 или 1e-16). Где я могу найти такую ​​вещь?

РЕДАКТИРОВАТЬ: Следуя совету Джона, я думаю, что имеет смысл определить эквивалентность. Одна идея состояла бы в том, чтобы центрировать их в числах, округленных до 15 наиболее значимых десятичных цифр. Другие числа будут округлены (любым последовательным способом - быстрее всего реализовать). Будет ли это иметь смысл? Какова будет лучшая реализация?

Ответы [ 4 ]

6 голосов
/ 02 января 2012

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

4 голосов
/ 02 января 2012

ИМХО Лучший подход - нормализовать значения перед добавлением или поиском значений. например с помощью округления.

Кстати: вы можете использовать TDoubleObjectHashMap, который поддерживает пользовательские стратегии хеширования и использует примитивные двойные ключи.

4 голосов
/ 02 января 2012

Я не совсем уверен, для чего он вам нужен, но вы можете реализовать обертку вокруг Double и переопределить ее методы hashCode() и equals(), чтобы соответствовать вашему поиску с "ограниченной точностью". Поэтому любая реализация Map будет устойчивой, потому что для поиска ключей она использует hashCode() и equals().

Конечно, ваша карта будет в форме Map<DoubleWrapper, smth>.

0 голосов
/ 02 января 2012

Суммируя ответы и комментарии выше, я получил следующую оболочку (которая, вероятно, не обрабатывает атм NaN):

public static class DoubleWrapper {
    private static final int PRECISION = 15;
    private final Double roundedValue;

    public DoubleWrapper(double value) {
        final double d = Math.ceil(Math.log10(value < 0 ? -value: value));
        final int power = PRECISION - (int) d;

        final double magnitude = Math.pow(10, power);
        final long shifted = Math.round(value*magnitude);
        roundedValue = shifted/magnitude;

    }

    public double getDouble() {
        return roundedValue;
    }

    @Override
    public boolean equals(Object obj) {
        return roundedValue.equals(obj);
    }

    @Override
    public int hashCode() {
        return roundedValue.hashCode();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...