Пример #1
0
        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)));
        }
Пример #2
0
 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));
 }
Пример #3
0
        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);
        }
Пример #4
0
        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;
            }
        }