Выдает ли Math.Round () надежные хеш-значения

1

Сохраняется ли для сравнения результат Math.Round(double, int) с == и использовать его, например, в качестве ключа HashSet<Double> или GroupBy(d=>Math.Round(d,1))?

Другими словами, существуют ли два удвоения x и y, для которых следующее утверждение не будет выполнено?

double x = ...;
double y = ...;
double xRound = Math.Round(x, 1);
double yRound = Math.Round(y, 1);

Debug.Assert(xRound==yRound || Math.Abs(xRound-yRound)>=0.1);

Скажем, я хотел бы сгруппировать список парных:

List<double> values = ...;
List<double> keys = values.GroupBy(d=>Math.Round(d,1)).Select(kv=>kv.Key).ToList();

Есть ли шанс, что я получу ключ со значением 0.100000000 и другим ключом со значением 0.09999999999?

(Я попытался разобрать разобранный сетевой источник Math.cs, но Round() в конечном итоге вызывает собственную функцию.)

Теги:
hash
double
rounding

1 ответ

1

Как правило, с учетом того же начального значения и тех же операций, тот же результат будет получен.

Однако, если вы (например) сделали:

double d1 = 10;
d1 /= 0.1;
double d2 = 25;
d2 /= 0.25;

то вы вполне можете обнаружить, что d1 и d2 не имеют одинакового значения (потому что IEEE754 может точно представлять 0.25, но не 0.1.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню