static long quaternion_arrtype_hash(PyObject *o) { quaternion q = ((PyQuaternionScalarObject *)o)->obval; long value = 0x456789; value = (10000004 * value) ^ _Py_HashDouble(q.w); value = (10000004 * value) ^ _Py_HashDouble(q.x); value = (10000004 * value) ^ _Py_HashDouble(q.y); value = (10000004 * value) ^ _Py_HashDouble(q.z); if (value == -1) value = -2; return value; }
/** * helper function that returns a Python ``__hash__``. * * \note consistent with the equivalent tuple of floats (CPython's 'tuplehash') */ Py_hash_t mathutils_array_hash(const float *array, size_t array_len) { int i; Py_uhash_t x; /* Unsigned for defined overflow behavior. */ Py_hash_t y; Py_uhash_t mult; Py_ssize_t len; mult = _PyHASH_MULTIPLIER; len = array_len; x = 0x345678UL; i = 0; while (--len >= 0) { y = _Py_HashDouble((double)(array[i++])); if (y == -1) return -1; x = (x ^ y) * mult; /* the cast might truncate len; that doesn't change hash stability */ mult += (Py_hash_t)(82520UL + len + len); } x += 97531UL; if (x == (Py_uhash_t)-1) x = -2; return x; }
static long halftype_hash(PyObject *obj) { double temp; temp = half_to_double(((PyHalfScalarObject *)obj)->obval); return _Py_HashDouble(*((double*)&temp)); }
static long complex_hash(PyComplexObject *v) { long hashreal, hashimag, combined; hashreal = _Py_HashDouble(v->cval.real); if (hashreal == -1) return -1; hashimag = _Py_HashDouble(v->cval.imag); if (hashimag == -1) return -1; /* Note: if the imaginary part is 0, hashimag is 0 now, * so the following returns hashreal unchanged. This is * important because numbers of different types that * compare equal must have the same hash value, so that * hash(x + 0*j) must equal hash(x). */ combined = hashreal + 1000003 * hashimag; if (combined == -1) combined = -2; return combined; }