public static int __hash__(double d) { // Python allows equality between floats, ints, and big ints. if ((d % 1) == 0) { // This double represents an integer, so it must hash like an integer. if (Int32.MinValue <= d && d <= Int32.MaxValue) { return(((int)d).GetHashCode()); } // Big integer BigInteger b = (BigInteger)d; return(BigIntegerOps.__hash__(b)); } // Special values if (double.IsInfinity(d)) { return(d > 0 ? 314159 : -271828); } else if (double.IsNaN(d)) { return(0); } return(d.GetHashCode()); }
public static object __getnewargs__(CodeContext context, BigInteger self) { #if !FEATURE_NUMERICS if (!Object.ReferenceEquals(self, null)) { return(PythonTuple.MakeTuple(BigIntegerOps.__new__(context, TypeCache.BigInteger, self))); } throw PythonOps.TypeErrorForBadInstance("__getnewargs__ requires a 'long' object but received a '{0}'", self); #else return(PythonTuple.MakeTuple(BigIntegerOps.__new__(context, TypeCache.BigInteger, self))); #endif }
public static object __round__(int number, BigInteger ndigits) { var result = BigIntegerOps.__round__(new BigInteger(number), ndigits); if (result.AsInt32(out var ret)) { return(ret); } // this path can be hit when number is close to int.MaxValue and ndigits is negative, // causing number to be rounded up and over int.MaxValue return(result); }
public static string hex(double self) { if (Double.IsPositiveInfinity(self)) { return("inf"); } else if (Double.IsNegativeInfinity(self)) { return("-inf"); } else if (Double.IsNaN(self)) { return("nan"); } #if SILVERLIGHT ulong bits = BitConverter.ToUInt64(BitConverter.GetBytes(self), 0); #else ulong bits = (ulong)BitConverter.DoubleToInt64Bits(self); #endif int exponent = (int)((bits >> 52) & 0x7ff) - 1023; long mantissa = (long)(bits & 0xfffffffffffff); StringBuilder res = new StringBuilder(); if ((bits & 0x8000000000000000) != 0) { // negative res.Append('-'); } if (exponent == -1023) { res.Append("0x0."); exponent++; } else { res.Append("0x1."); } res.Append(StringFormatSpec.FromString("013").AlignNumericText(BigIntegerOps.AbsToHex(mantissa, true), mantissa == 0, true)); res.Append("p"); if (exponent >= 0) { res.Append('+'); } res.Append(exponent.ToString()); return(res.ToString()); }
public static object Power(int x, int power) { if (power == 0) { return(1); } if (power < 0) { if (x == 0) { throw PythonOps.ZeroDivisionError("0.0 cannot be raised to a negative power"); } return(DoubleOps.Power(x, power)); } int factor = x; int result = 1; int savePower = power; try { checked { while (power != 0) { if ((power & 1) != 0) { result = result * factor; } if (power == 1) { break; // prevent overflow } factor = factor * factor; power >>= 1; } return(result); } } catch (OverflowException) { return(BigIntegerOps.Power((BigInteger)x, savePower)); } }
internal static bool TryToFloat(CodeContext context, object /*?*/ value, out double result) { if (value is double d) { result = d; } else if (value is int i) { result = i; } else if (value is BigInteger bi) { result = BigIntegerOps.ToDouble(bi); } else if (TryInvokeFloat(context, value, out result)) { // pass } else if (value is Extensible <double> ed) { result = ed.Value; } else if (value is Extensible <BigInteger> ebi) { result = BigIntegerOps.ToDouble(ebi.Value); } else if (PythonOps.TryToIndex(value, out object ireal)) // Python 3.8: fall back on __index__ { result = ireal switch { int ii => ii, BigInteger bii => BigIntegerOps.ToDouble(bii), _ => throw new InvalidOperationException("Unreachable code") }; } else { return(false); } return(true);
public static object __getnewargs__(CodeContext context, BigInteger self) { return(PythonTuple.MakeTuple(BigIntegerOps.__new__(context, TypeCache.BigInteger, self))); }
public static object Power(int x, BigInteger power, BigInteger qmod) { return(BigIntegerOps.Power((BigInteger)x, power, qmod)); }
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; } }
public static object from_bytes(CodeContext context, PythonType type, object bytes, [NotNone] string byteorder, bool signed = false) // TODO: signed should be a keyword only argument => BigIntegerOps.from_bytes(context, type, bytes, byteorder, signed);
public static BigInteger BitwiseOr(bool x, BigInteger y) { return(BigIntegerOps.BitwiseOr(x ? 1 : 0, y)); }
public static BigInteger BitwiseOr(BigInteger x, bool y) { return(BigIntegerOps.BitwiseOr(y ? 1 : 0, x)); }
public static BigInteger ExclusiveOr(bool x, BigInteger y) { return(BigIntegerOps.ExclusiveOr(x ? 1 : 0, y)); }
public static BigInteger ExclusiveOr(BigInteger x, bool y) { return(BigIntegerOps.ExclusiveOr(y ? 1 : 0, x)); }