public static double TrueDivide([NotNull]BigInteger x, [NotNull]BigInteger y) { if (y == BigInteger.Zero) { throw new DivideByZeroException(); } // first see if we can keep the two inputs as floats to give a precise result double fRes, fDiv; if (x.TryToFloat64(out fRes) && y.TryToFloat64(out fDiv)) { return fRes / fDiv; } // otherwise give the user the truncated result if the result fits in a float BigInteger rem; BigInteger res = BigInteger.DivRem(x, y, out rem); if (res.TryToFloat64(out fRes)) { if(rem != BigInteger.Zero) { // try and figure out the fractional portion BigInteger fraction = y / rem; if (fraction.TryToFloat64(out fDiv)) { if (fDiv != 0) { fRes += 1 / fDiv; } } } return fRes; } // otherwise report an error throw PythonOps.OverflowError("long/long too large for a float"); }
public static double Abs(Complex x) { double res = x.Abs(); if (double.IsInfinity(res) && !double.IsInfinity(x.Real) && !double.IsInfinity(x.Imaginary())) { throw PythonOps.OverflowError("absolute value too large"); } return(res); }
public static double TrueDivide([NotNull] BigInteger x, [NotNull] BigInteger y) { if (y == BigInteger.Zero) { throw new DivideByZeroException(); } // first see if we can keep the two inputs as floats to give a precise result double fRes, fDiv; if (x.TryToFloat64(out fRes) && y.TryToFloat64(out fDiv)) { return(fRes / fDiv); } // otherwise give the user the truncated result if the result fits in a float BigInteger rem; BigInteger res = BigInteger.DivRem(x, y, out rem); if (res.TryToFloat64(out fRes)) { if (rem != BigInteger.Zero) { // scale remainder so that the fraction could be integer BigInteger fraction = BigInteger.DivRem(rem << 56, y, out rem); // adding 7 tailing zero bytes, bigger than sys.float_info.mant_dig // round to nearest FPU if (rem.IsPositive()) { if (rem >= y / 2) { fraction += 1; } } else { if (rem <= -y / 2) { fraction -= 1; } } if (fraction.TryToFloat64(out fDiv)) { fRes += fDiv / (1L << 56); } } return(fRes); } // otherwise report an error throw PythonOps.OverflowError("integer division result too large for a float"); }
public static PythonTuple __coerce__(CodeContext context, double x, object o) { // called via builtin.coerce() double d = (double)__new__(context, TypeCache.Double, o); if (Double.IsInfinity(d)) { throw PythonOps.OverflowError("number too big"); } return(PythonTuple.MakeTuple(x, d)); }
public static BigInteger /*!*/ __long__(double self) { if (double.IsInfinity(self)) { throw PythonOps.OverflowError("cannot convert float infinity to integer"); } else if (double.IsNaN(self)) { throw PythonOps.ValueError("cannot convert float NaN to integer"); } else { return((BigInteger)self); } }
public static double Abs(Complex x) { #if CLR2 double res = x.Abs(); #else // TODO: remove after CodePlex 26224 and MS internal 861649 are resolved double res = MathUtils.Hypot(x.Real, x.Imaginary); #endif if (double.IsInfinity(res) && !double.IsInfinity(x.Real) && !double.IsInfinity(x.Imaginary())) { throw PythonOps.OverflowError("absolute value too large"); } return(res); }
public static double Abs(Complex x) { // CPython returns inf even if one of the values is NaN if (double.IsInfinity(x.Real) || double.IsInfinity(x.Imaginary)) { return(double.PositiveInfinity); } double res = x.Abs(); if (double.IsInfinity(res) && !double.IsInfinity(x.Real) && !double.IsInfinity(x.Imaginary)) { throw PythonOps.OverflowError("absolute value too large"); } return(res); }
public static Bytes to_bytes(BigInteger value, int length, string byteorder, bool signed = false) { // TODO: signed should be a keyword only argument // TODO: should probably be moved to IntOps.Generated and included in all types if (length < 0) { throw PythonOps.ValueError("length argument must be non-negative"); } if (!signed && value < 0) { throw PythonOps.OverflowError("can't convert negative int to unsigned"); } bool isLittle = byteorder == "little"; if (!isLittle && byteorder != "big") { throw PythonOps.ValueError("byteorder must be either 'little' or 'big'"); } var reqLength = (bit_length(value) + (signed ? 1 : 0)) / 8; if (reqLength > length) { throw PythonOps.OverflowError("int too big to convert"); } var bytes = value.ToByteArray(); IEnumerable <byte> res = bytes; if (length > bytes.Length) { res = res.Concat(Enumerable.Repeat <byte>((value < 0) ? (byte)0xff : (byte)0, length - bytes.Length)); } else if (length < bytes.Length) { res = res.Take(length); } if (!isLittle) { res = res.Reverse(); } return(Bytes.Make(res.ToArray())); }
public static double Power(double x, double y) { if (x == 0.0 && y < 0.0) { throw PythonOps.ZeroDivisionError("0.0 cannot be raised to a negative power"); } if (x < 0 && (Math.Floor(y) != y)) { throw PythonOps.ValueError("negative number cannot be raised to fraction"); } double result = Math.Pow(x, y); if (double.IsInfinity(result)) { throw PythonOps.OverflowError("result too large"); } return(result); }
public static object __int__(double d) { if (Int32.MinValue <= d && d <= Int32.MaxValue) { return((int)d); } else if (double.IsInfinity(d)) { throw PythonOps.OverflowError("cannot convert float infinity to integer"); } else if (double.IsNaN(d)) { throw PythonOps.ValueError("cannot convert float NaN to integer"); } else { return((BigInteger)d); } }
public static PythonTuple as_integer_ratio(double self) { if (Double.IsInfinity(self)) { throw PythonOps.OverflowError("Cannot pass infinity to float.as_integer_ratio."); } else if (Double.IsNaN(self)) { throw PythonOps.ValueError("Cannot pass nan to float.as_integer_ratio."); } BigInteger dem = 1; while ((self % 1) != 0.0) { self *= 2; dem *= 2; } return(PythonTuple.MakeTuple((BigInteger)self, dem)); }
public static Bytes to_bytes(Int64 value, int length, [NotNone] string byteorder, bool signed = false) { // TODO: signed should be a keyword only argument bool isLittle = (byteorder == "little"); if (!isLittle && byteorder != "big") { throw PythonOps.ValueError("byteorder must be either 'little' or 'big'"); } if (length < 0) { throw PythonOps.ValueError("length argument must be non-negative"); } if (!signed && value < 0) { throw PythonOps.OverflowError("can't convert negative int to unsigned"); } if (value == 0) { return(Bytes.Make(new byte[length])); } var bytes = new byte[length]; int cur, end, step; if (isLittle) { cur = 0; end = length; step = 1; } else { cur = length - 1; end = -1; step = -1; } if (!signed || value >= 0) { ulong uvalue = unchecked ((ulong)value); do { if (cur == end) { ThrowOverflow(); } bytes[cur] = (byte)(uvalue & 0xFF); uvalue >>= 8; cur += step; } while (uvalue != 0); } else { byte curbyte; do { if (cur == end) { ThrowOverflow(); } bytes[cur] = curbyte = (byte)(value & 0xFF); value >>= 8; cur += step; } while (value != -1 || (curbyte & 0x80) == 0); while (cur != end) { bytes[cur] = 0xFF; cur += step; } } return(Bytes.Make(bytes));
public static string /*!*/ __format__(CodeContext /*!*/ context, BigInteger /*!*/ self, [NotNull] string /*!*/ formatSpec) { StringFormatSpec spec = StringFormatSpec.FromString(formatSpec); if (spec.Precision != null) { throw PythonOps.ValueError("Precision not allowed in integer format specifier"); } BigInteger val = self; if (self < 0) { val = -self; } string digits; switch (spec.Type) { case 'n': CultureInfo culture = context.LanguageContext.NumericCulture; if (culture == CultureInfo.InvariantCulture) { // invariant culture maps to CPython's C culture, which doesn't // include any formatting info. goto case 'd'; } digits = FormattingHelper.ToCultureString(val, context.LanguageContext.NumericCulture.NumberFormat, spec); break; case null: case 'd': if (spec.ThousandsComma) { var width = spec.Width ?? 0; // If we're inserting commas, and we're padding with leading zeros. // AlignNumericText won't know where to place the commas, // so force .Net to help us out here. if (spec.Fill.HasValue && spec.Fill.Value == '0' && width > 1) { digits = val.ToString(FormattingHelper.ToCultureString(self, FormattingHelper.InvariantCommaNumberInfo, spec)); } else { digits = val.ToString("#,0", CultureInfo.InvariantCulture); } } else { digits = val.ToString("D", CultureInfo.InvariantCulture); } break; case '%': if (spec.ThousandsComma) { digits = val.ToString("#,0.000000%", CultureInfo.InvariantCulture); } else { digits = val.ToString("0.000000%", CultureInfo.InvariantCulture); } break; case 'e': if (spec.ThousandsComma) { digits = val.ToString("#,0.000000e+00", CultureInfo.InvariantCulture); } else { digits = val.ToString("0.000000e+00", CultureInfo.InvariantCulture); } break; case 'E': if (spec.ThousandsComma) { digits = val.ToString("#,0.000000E+00", CultureInfo.InvariantCulture); } else { digits = val.ToString("0.000000E+00", CultureInfo.InvariantCulture); } break; case 'f': case 'F': if (spec.ThousandsComma) { digits = val.ToString("#,########0.000000", CultureInfo.InvariantCulture); } else { digits = val.ToString("#########0.000000", CultureInfo.InvariantCulture); } break; case 'g': if (val >= 1000000) { digits = val.ToString("0.#####e+00", CultureInfo.InvariantCulture); } else if (spec.ThousandsComma) { goto case 'd'; } else { digits = val.ToString(CultureInfo.InvariantCulture); } break; case 'G': if (val >= 1000000) { digits = val.ToString("0.#####E+00", CultureInfo.InvariantCulture); } else if (spec.ThousandsComma) { goto case 'd'; } else { digits = val.ToString(CultureInfo.InvariantCulture); } break; case 'X': digits = AbsToHex(val, false); break; case 'x': digits = AbsToHex(val, true); break; case 'o': // octal digits = ToOctal(val, true); break; case 'b': // binary digits = ToBinary(val, false, true); break; case 'c': // single char int iVal; if (spec.Sign != null) { throw PythonOps.ValueError("Sign not allowed with integer format specifier 'c'"); } else if (!self.AsInt32(out iVal)) { throw PythonOps.OverflowError("long int too large to convert to int"); } else if (iVal < 0 || iVal > 0xFF) { throw PythonOps.OverflowError("%c arg not in range(0x10000)"); } digits = ScriptingRuntimeHelpers.CharToString((char)iVal); break; default: throw PythonOps.ValueError("Unknown format code '{0}'", spec.Type.ToString()); } Debug.Assert(digits[0] != '-'); return(spec.AlignNumericText(digits, self.IsZero(), self.IsPositive())); }
static void ThrowOverflow() => throw PythonOps.OverflowError("int too big to convert");
public static string __format__(CodeContext /*!*/ context, int self, [NotNull] string /*!*/ formatSpec) { StringFormatSpec spec = StringFormatSpec.FromString(formatSpec); if (spec.Precision != null) { throw PythonOps.ValueError("Precision not allowed in integer format specifier"); } string digits; switch (spec.Type) { case 'n': CultureInfo culture = PythonContext.GetContext(context).NumericCulture; if (culture == CultureInfo.InvariantCulture) { // invariant culture maps to CPython's C culture, which doesn't // include any formatting info. goto case 'd'; } digits = self.ToString("N0", PythonContext.GetContext(context).NumericCulture); break; case null: case 'd': if (spec.ThousandsComma) { digits = self.ToString("#,0", CultureInfo.InvariantCulture); } else { digits = self.ToString("D", CultureInfo.InvariantCulture); } break; case '%': if (spec.ThousandsComma) { digits = self.ToString("#,0.000000%", CultureInfo.InvariantCulture); } else { digits = self.ToString("0.000000%", CultureInfo.InvariantCulture); } break; case 'e': if (spec.ThousandsComma) { digits = self.ToString("#,0.000000e+00", CultureInfo.InvariantCulture); } else { digits = self.ToString("0.000000e+00", CultureInfo.InvariantCulture); } break; case 'E': if (spec.ThousandsComma) { digits = self.ToString("#,0.000000E+00", CultureInfo.InvariantCulture); } else { digits = self.ToString("0.000000E+00", CultureInfo.InvariantCulture); } break; case 'f': case 'F': if (spec.ThousandsComma) { digits = self.ToString("#,########0.000000", CultureInfo.InvariantCulture); } else { digits = self.ToString("#########0.000000", CultureInfo.InvariantCulture); } break; case 'g': if (self >= 1000000 || self <= -1000000) { digits = self.ToString("0.#####e+00", CultureInfo.InvariantCulture); } else if (spec.ThousandsComma) { digits = self.ToString("#,0", CultureInfo.InvariantCulture); } else { digits = self.ToString(CultureInfo.InvariantCulture); } break; case 'G': if (self >= 1000000 || self <= -1000000) { digits = self.ToString("0.#####E+00", CultureInfo.InvariantCulture); } else if (spec.ThousandsComma) { digits = self.ToString("#,0", CultureInfo.InvariantCulture); } else { digits = self.ToString(CultureInfo.InvariantCulture); } break; case 'X': digits = ToHex(self, false); break; case 'x': digits = ToHex(self, true); break; case 'o': // octal digits = ToOctal(self, true); break; case 'b': // binary digits = ToBinary(self, false); break; case 'c': // single char if (spec.Sign != null) { throw PythonOps.ValueError("Sign not allowed with integer format specifier 'c'"); } if (self < 0 || self > 0xFF) { throw PythonOps.OverflowError("%c arg not in range(0x10000)"); } digits = ScriptingRuntimeHelpers.CharToString((char)self); break; default: throw PythonOps.ValueError("Unknown format code '{0}'", spec.Type.ToString()); } if (self < 0 && digits[0] == '-') { digits = digits.Substring(1); } return(spec.AlignNumericText(digits, self == 0, self > 0)); }
public static string __format__(CodeContext /*!*/ context, int self, [NotNull] string /*!*/ formatSpec) { StringFormatSpec spec = StringFormatSpec.FromString(formatSpec); if (spec.Precision != null) { throw PythonOps.ValueError("Precision not allowed in integer format specifier"); } string digits; int width = 0; switch (spec.Type) { case 'n': CultureInfo culture = context.LanguageContext.NumericCulture; if (culture == CultureInfo.InvariantCulture) { // invariant culture maps to CPython's C culture, which doesn't // include any formatting info. goto case 'd'; } width = spec.Width ?? 0; // If we're padding with leading zeros and we might be inserting // culture sensitive number group separators. (i.e. commas) // So use FormattingHelper.ToCultureString for that support. if (spec.Fill.HasValue && spec.Fill.Value == '0' && width > 1) { digits = FormattingHelper.ToCultureString(self, culture.NumberFormat, spec); } else { digits = self.ToString("N0", culture); } break; case null: case 'd': if (spec.ThousandsComma) { width = spec.Width ?? 0; // If we're inserting commas, and we're padding with leading zeros. // AlignNumericText won't know where to place the commas, // so use FormattingHelper.ToCultureString for that support. if (spec.Fill.HasValue && spec.Fill.Value == '0' && width > 1) { digits = FormattingHelper.ToCultureString(self, FormattingHelper.InvariantCommaNumberInfo, spec); } else { digits = self.ToString("#,0", CultureInfo.InvariantCulture); } } else { digits = self.ToString("D", CultureInfo.InvariantCulture); } break; case '%': if (spec.ThousandsComma) { digits = self.ToString("#,0.000000%", CultureInfo.InvariantCulture); } else { digits = self.ToString("0.000000%", CultureInfo.InvariantCulture); } break; case 'e': if (spec.ThousandsComma) { digits = self.ToString("#,0.000000e+00", CultureInfo.InvariantCulture); } else { digits = self.ToString("0.000000e+00", CultureInfo.InvariantCulture); } break; case 'E': if (spec.ThousandsComma) { digits = self.ToString("#,0.000000E+00", CultureInfo.InvariantCulture); } else { digits = self.ToString("0.000000E+00", CultureInfo.InvariantCulture); } break; case 'f': case 'F': if (spec.ThousandsComma) { digits = self.ToString("#,########0.000000", CultureInfo.InvariantCulture); } else { digits = self.ToString("#########0.000000", CultureInfo.InvariantCulture); } break; case 'g': if (self >= 1000000 || self <= -1000000) { digits = self.ToString("0.#####e+00", CultureInfo.InvariantCulture); } else if (spec.ThousandsComma) { // Handle the common case in 'd'. goto case 'd'; } else { digits = self.ToString(CultureInfo.InvariantCulture); } break; case 'G': if (self >= 1000000 || self <= -1000000) { digits = self.ToString("0.#####E+00", CultureInfo.InvariantCulture); } else if (spec.ThousandsComma) { // Handle the common case in 'd'. goto case 'd'; } else { digits = self.ToString(CultureInfo.InvariantCulture); } break; case 'X': digits = ToHex(self, false); break; case 'x': digits = ToHex(self, true); break; case 'o': // octal digits = ToOctal(self, true); break; case 'b': // binary digits = ToBinary(self, false); break; case 'c': // single char if (spec.Sign != null) { throw PythonOps.ValueError("Sign not allowed with integer format specifier 'c'"); } if (self < 0 || self > 0xFF) { throw PythonOps.OverflowError("%c arg not in range(0x10000)"); } digits = ScriptingRuntimeHelpers.CharToString((char)self); break; default: throw PythonOps.ValueError("Unknown format code '{0}'", spec.Type.ToString()); } if (self < 0 && digits[0] == '-') { digits = digits.Substring(1); } return(spec.AlignNumericText(digits, self == 0, self > 0)); }
public static string /*!*/ __format__(CodeContext /*!*/ context, BigInteger /*!*/ self, [NotNull] string /*!*/ formatSpec) { StringFormatSpec spec = StringFormatSpec.FromString(formatSpec); if (spec.Precision != null) { throw PythonOps.ValueError("Precision not allowed in integer format specifier"); } BigInteger val = self; if (self < 0) { val = -self; } string digits; switch (spec.Type) { case 'n': CultureInfo culture = PythonContext.GetContext(context).NumericCulture; if (culture == CultureInfo.InvariantCulture) { // invariant culture maps to CPython's C culture, which doesn't // include any formatting info. goto case 'd'; } digits = ToCultureString(val, PythonContext.GetContext(context).NumericCulture); break; #if CLR2 case null: case 'd': digits = val.ToString(); break; case '%': if (val == BigInteger.Zero) { digits = "0.000000%"; } else { digits = val.ToString() + "00.000000%"; } break; case 'e': digits = ToExponent(val, true, 6, 7); break; case 'E': digits = ToExponent(val, false, 6, 7); break; case 'f': if (val != BigInteger.Zero) { digits = val.ToString() + ".000000"; } else { digits = "0.000000"; } break; case 'F': if (val != BigInteger.Zero) { digits = val.ToString() + ".000000"; } else { digits = "0.000000"; } break; case 'g': if (val >= 1000000) { digits = ToExponent(val, true, 0, 6); } else { digits = val.ToString(); } break; case 'G': if (val >= 1000000) { digits = ToExponent(val, false, 0, 6); } else { digits = val.ToString(); } break; #else case null: case 'd': if (spec.ThousandsComma) { digits = val.ToString("#,0", CultureInfo.InvariantCulture); } else { digits = val.ToString("D", CultureInfo.InvariantCulture); } break; case '%': if (spec.ThousandsComma) { digits = val.ToString("#,0.000000%", CultureInfo.InvariantCulture); } else { digits = val.ToString("0.000000%", CultureInfo.InvariantCulture); } break; case 'e': if (spec.ThousandsComma) { digits = val.ToString("#,0.000000e+00", CultureInfo.InvariantCulture); } else { digits = val.ToString("0.000000e+00", CultureInfo.InvariantCulture); } break; case 'E': if (spec.ThousandsComma) { digits = val.ToString("#,0.000000E+00", CultureInfo.InvariantCulture); } else { digits = val.ToString("0.000000E+00", CultureInfo.InvariantCulture); } break; case 'f': case 'F': if (spec.ThousandsComma) { digits = val.ToString("#,########0.000000", CultureInfo.InvariantCulture); } else { digits = val.ToString("#########0.000000", CultureInfo.InvariantCulture); } break; case 'g': if (val >= 1000000) { digits = val.ToString("0.#####e+00", CultureInfo.InvariantCulture); } else if (spec.ThousandsComma) { digits = val.ToString("#,0", CultureInfo.InvariantCulture); } else { digits = val.ToString(CultureInfo.InvariantCulture); } break; case 'G': if (val >= 1000000) { digits = val.ToString("0.#####E+00", CultureInfo.InvariantCulture); } else if (spec.ThousandsComma) { digits = val.ToString("#,0", CultureInfo.InvariantCulture); } else { digits = val.ToString(CultureInfo.InvariantCulture); } break; #endif case 'X': digits = AbsToHex(val, false); break; case 'x': digits = AbsToHex(val, true); break; case 'o': // octal digits = ToOctal(val, true); break; case 'b': // binary digits = ToBinary(val, false, true); break; case 'c': // single char int iVal; if (spec.Sign != null) { throw PythonOps.ValueError("Sign not allowed with integer format specifier 'c'"); } else if (!self.AsInt32(out iVal)) { throw PythonOps.OverflowError("long int too large to convert to int"); } else if (iVal < 0 || iVal > 0xFF) { throw PythonOps.OverflowError("%c arg not in range(0x10000)"); } digits = ScriptingRuntimeHelpers.CharToString((char)iVal); break; default: throw PythonOps.ValueError("Unknown format code '{0}'", spec.Type.ToString()); } Debug.Assert(digits[0] != '-'); return(spec.AlignNumericText(digits, self.IsZero(), self.IsPositive())); }
private static Exception HexStringOverflow() { return(PythonOps.OverflowError("hexadecimal value too large to represent as a float")); }