Почему «397» используется для переопределения ReSharper GetHashCode?

150

Как и многие из вас, я использую ReSharper для ускорения процесса разработки. Когда вы используете его для переопределения членов равенства класса, генерируемый им код для GetHashCode () выглядит следующим образом:

    public override int GetHashCode()
    {
        unchecked
        {
            int result = (Key != null ? Key.GetHashCode() : 0);
            result = (result * 397) ^ (EditableProperty != null ? EditableProperty.GetHashCode() : 0);
            result = (result * 397) ^ ObjectId;
            return result;
        }
    }

Конечно, у меня есть некоторые из моих собственных членов, но я хочу знать, почему 397?

  • РЕДАКТИРОВАТЬ: Таким образом, мой вопрос будет лучше сформулировать, есть ли что-то «особенное» в простом числе 397 за исключением того, что оно является простым числом?
программист
источник

Ответы:

166

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

Ник Джонсон
источник
73
И 397 счастлив. Разве мы все не хотим быть счастливыми?
Рассел Б
2
Хорошо, но почему оно должно быть простым, и почему оно должно быть именно такой величины? Если оно должно быть простым, почему бы не 2 или 2147483647? Я думаю, чтобы получить хорошую мутацию (и единственная причина для этого умножения - мутация), нам не нужно число, чтобы быть простым. Нам нужен мультипликатор, чтобы иметь относительно одинаковое число или нули и единицы, предпочтительно без явных шаблонов. 397 = 110001101b соответствует. Все еще не уверен насчет величины.
Андрей К
5
Как сказал Ник, в этом нет ничего особенного. Это НЕ ДОЛЖЕН быть такого размера, это просто число, достаточно большое, чтобы при вычислении хеша результат переполнялся (так как GetHashCode () возвращает Int32). Выбор простого числа просто полезен для распределения, у меня нет математической степени, поэтому я не буду пытаться объяснить это, но умножение на простое будет иметь результат, который лучше распределен, чем умножение на любое другое произвольное число.
Бен Рэндалл
16

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

kybernetikos
источник