public static int __hash__(BigInteger self) { // check if it's in the Int64 or UInt64 range, and use the built-in hashcode for that instead // this ensures that objects added to dictionaries as (U)Int64 can be looked up with Python longs if (self.AsInt64(out long i64)) { return(Int64Ops.__hash__(i64)); } else if (self.AsUInt64(out ulong u64)) { return(UInt64Ops.__hash__(u64)); } if (self.IsNegative()) { self = -self; var h = unchecked (-(int)((self >= int.MaxValue) ? (self % int.MaxValue) : self)); if (h == -1) { return(-2); } return(h); } return(unchecked ((int)((self >= int.MaxValue) ? (self % int.MaxValue) : self))); }
public static object LeftShift(int x, int y) { if (y < 0) { throw PythonOps.ValueError("negative shift count"); } if (y > 31 || (x > 0 && x > (Int32.MaxValue >> y)) || (x < 0 && x < (Int32.MinValue >> y))) { return(Int64Ops.LeftShift((long)x, y)); } return(ScriptingRuntimeHelpers.Int32ToObject(x << y)); }
public static int __hash__(BigInteger self) { // TODO: we might need our own hash code implementation. This avoids assertion failure. if (self == -2147483648) { return(-2147483648); } // check if it's in the Int64 or UInt64 range, and use the built-in hashcode for that instead // this ensures that objects added to dictionaries as (U)Int64 can be looked up with Python longs Int64 i64; if (self.AsInt64(out i64)) { return(Int64Ops.__hash__(i64)); } else { UInt64 u64; if (self.AsUInt64(out u64)) { return(UInt64Ops.__hash__(u64)); } } // Call the DLR's BigInteger hash function, which will return an int32 representation of // b if b is within the int32 range. We use that as an optimization for hashing, and // assert the assumption below. int hash = self.GetHashCode(); #if DEBUG int i; if (self.AsInt32(out i)) { Debug.Assert(i == hash, String.Format("hash({0}) == {1}", i, hash)); } #endif return(hash); }
public static int __hash__(double d) { // Special values if (double.IsPositiveInfinity(d)) { return(314159); } if (double.IsNegativeInfinity(d)) { return(-314159); } if (double.IsNaN(d)) { return(0); } if (d == 0) { return(0); } // it's an integer! if (d == Math.Truncate(d)) { // Use this constant since long.MaxValue doesn't cast precisely to a double const double maxValue = (ulong)long.MaxValue + 1; if (long.MinValue <= d && d < maxValue) { return(Int64Ops.__hash__((long)d)); } return(BigIntegerOps.__hash__((BigInteger)d)); } DecomposeDouble(d, out int sign, out int exponent, out long mantissa); // make sure the mantissa is not even while ((mantissa & 1) == 0) { mantissa >>= 1; exponent++; } Debug.Assert(exponent <= 0); var exp = exponent % 31; var invmod = exp == 0 ? 1 : (1 << (31 + exp)); return(unchecked ((int)(sign * (((mantissa % int.MaxValue) * invmod) % int.MaxValue)))); void DecomposeDouble(in double x, out int Sign, out int Exponent, out long Mantissa) { Debug.Assert(x != 0 && !double.IsInfinity(x) && !double.IsNaN(x)); var RawBits = (ulong)BitConverter.DoubleToInt64Bits(x); var RawSign = (int)(RawBits >> 63); var RawExponent = (int)(RawBits >> 52) & 0x7FF; var RawMantissa = (long)(RawBits & 0x000FFFFFFFFFFFFF); var IsDenormal = RawExponent == 0 && RawMantissa != 0; // assumes not infinity, not zero and not NaN Sign = 1 - RawSign * 2; Mantissa = IsDenormal ? RawMantissa : RawMantissa | 0x0010000000000000; Exponent = IsDenormal ? -1074 : RawExponent - 1075; } }