internal static PythonList Split(this IList <byte> bytes, IList <byte>?sep, int maxsplit, Func <List <byte>, IList <byte> > ctor) { if (sep == null) { if (maxsplit == 0) { // Corner case for CPython compatibility PythonList result = new PythonList(1); result.AddNoLock(ctor(bytes.LeftStrip() ?? bytes as List <byte> ?? new List <byte>(bytes))); return(result); } return(SplitInternal(bytes, null, maxsplit, ctor)); } if (sep.Count == 0) { throw PythonOps.ValueError("empty separator"); } else { return(SplitInternal(bytes, sep, maxsplit, ctor)); } }
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())); }
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 void WriteObject(object o) { List <object> infinite = PythonOps.GetReprInfinite(); if (infinite.Contains(o)) { throw PythonOps.ValueError("Marshaled data contains infinite cycle"); } int index = infinite.Count; infinite.Add(o); try { if (o == null) { _bytes.Add((byte)'N'); } else if (o == ScriptingRuntimeHelpers.True || (o is bool && (bool)o)) { _bytes.Add((byte)'T'); } else if (o == ScriptingRuntimeHelpers.False || (o is bool && (!(bool)o))) { _bytes.Add((byte)'F'); } else if (o is IList <byte> ) { WriteBytes(o as IList <byte>); } else if (o is string) { WriteString(o as string); } else if (o is int) { WriteInt((int)o); } else if (o is float) { WriteFloat((float)o); } else if (o is double) { WriteFloat((double)o); } else if (o is long) { WriteLong((long)o); } else if (o.GetType() == typeof(PythonList)) { WriteList(o); } else if (o.GetType() == typeof(PythonDictionary)) { WriteDict(o); } else if (o.GetType() == typeof(PythonTuple)) { WriteTuple(o); } else if (o.GetType() == typeof(SetCollection)) { WriteSet(o); } else if (o.GetType() == typeof(FrozenSetCollection)) { WriteFrozenSet(o); } else if (o is BigInteger) { WriteInteger((BigInteger)o); } else if (o is Complex) { WriteComplex((Complex)o); } else if (o == PythonExceptions.StopIteration) { WriteStopIteration(); } else { throw PythonOps.ValueError("unmarshallable object" + o.GetType().ToString()); } } finally { infinite.RemoveAt(index); } }
public object ReadObject() { while (_myBytes.MoveNext()) { byte cur = _myBytes.Current; object res; switch ((char)cur) { case '(': PushStack(StackType.Tuple); break; case '[': PushStack(StackType.List); break; case '{': PushStack(StackType.Dict); break; case '<': PushStack(StackType.Set); break; case '>': PushStack(StackType.FrozenSet); break; case '0': // end of dictionary if (_stack == null || _stack.Count == 0) { throw PythonOps.ValueError("bad marshal data"); } _stack.Peek().StackCount = 0; break; // case 'c': break; default: res = YieldSimple(); if (_stack == null) { return(res); } do { res = UpdateStack(res); } while (res != null && _stack.Count > 0); if (_stack.Count == 0) { return(_result); } continue; } // handle empty lists/tuples... if (_stack != null && _stack.Count > 0 && _stack.Peek().StackCount == 0) { ProcStack ps = _stack.Pop(); res = ps.StackObj; if (ps.StackType == StackType.Tuple) { res = PythonTuple.Make(res); } else if (ps.StackType == StackType.FrozenSet) { res = FrozenSetCollection.Make(TypeCache.FrozenSet, res); } if (_stack.Count > 0) { // empty list/tuple do { res = UpdateStack(res); } while (res != null && _stack.Count > 0); if (_stack.Count == 0) { break; } } else { _result = res; break; } } } return(_result); }
public static double Power(double x, double y) { if (x == 1.0 || y == 0.0) { return(1.0); } else if (double.IsNaN(x) || double.IsNaN(y)) { return(double.NaN); } else if (x == 0.0) { if (y > 0.0) { // preserve sign if y is a positive, odd int if (y % 2.0 == 1.0) { return(x); } return(0.0); } else if (y == 0.0) { return(1.0); } else if (double.IsNegativeInfinity(y)) { return(double.PositiveInfinity); } throw PythonOps.ZeroDivisionError("0.0 cannot be raised to a negative power"); } else if (double.IsPositiveInfinity(y)) { if (x > 1.0 || x < -1.0) { return(double.PositiveInfinity); } else if (x == -1.0) { return(1.0); } return(0.0); } else if (double.IsNegativeInfinity(y)) { if (x > 1.0 || x < -1.0) { return(0.0); } else if (x == -1.0) { return(1.0); } return(double.PositiveInfinity); } else if (double.IsNegativeInfinity(x)) { // preserve negative sign if y is an odd int if (Math.Abs(y % 2.0) == 1.0) { return(y > 0 ? double.NegativeInfinity : NegativeZero); } else { return(y > 0 ? double.PositiveInfinity : 0.0); } } else if (x < 0 && (Math.Floor(y) != y)) { throw PythonOps.ValueError("negative number cannot be raised to fraction"); } return(PythonOps.CheckMath(x, y, Math.Pow(x, y))); }
private static Exception InvalidHexString() { return(PythonOps.ValueError("invalid hexadecimal floating-point string")); }
public static object fromhex(CodeContext /*!*/ context, PythonType /*!*/ cls, string self) { if (String.IsNullOrEmpty(self)) { throw PythonOps.ValueError("expected non empty string"); } self = self.Trim(_whitespace); // look for inf, infinity, nan, etc... double?specialRes = TryParseSpecialFloat(self); if (specialRes != null) { return(specialRes.Value); } // nothing special, parse the hex... if (_fromHexRegex == null) { _fromHexRegex = new Regex("\\A\\s*(?<sign>[-+])?(?:0[xX])?(?<integer>[0-9a-fA-F]+)?(?<fraction>\\.[0-9a-fA-F]*)?(?<exponent>[pP][-+]?[0-9]+)?\\s*\\z"); } Match match = _fromHexRegex.Match(self); if (!match.Success) { throw InvalidHexString(); } var sign = match.Groups["sign"]; var integer = match.Groups["integer"]; var fraction = match.Groups["fraction"]; var exponent = match.Groups["exponent"]; bool isNegative = sign.Success && sign.Value == "-"; BigInteger intVal; if (integer.Success) { intVal = LiteralParser.ParseBigInteger(integer.Value, 16); } else { intVal = BigInteger.Zero; } // combine the integer and fractional parts into one big int BigInteger finalBits; int decimalPointBit = 0; // the number of bits of fractions that we have if (fraction.Success) { BigInteger fractionVal = 0; // add the fractional bits to the integer value for (int i = 1; i < fraction.Value.Length; i++) { char chr = fraction.Value[i]; int val; if (chr >= '0' && chr <= '9') { val = chr - '0'; } else if (chr >= 'a' && chr <= 'f') { val = 10 + chr - 'a'; } else if (chr >= 'A' && chr <= 'Z') { val = 10 + chr - 'A'; } else { // unreachable due to the regex throw new InvalidOperationException(); } fractionVal = (fractionVal << 4) | val; decimalPointBit += 4; } finalBits = (intVal << decimalPointBit) | fractionVal; } else { // we only have the integer value finalBits = intVal; } if (exponent.Success) { int exponentVal = 0; if (!Int32.TryParse(exponent.Value.Substring(1), out exponentVal)) { if (exponent.Value.ToLowerAsciiTriggered().StartsWith("p-") || finalBits == BigInteger.Zero) { double zeroRes = isNegative ? NegativeZero : PositiveZero; if (cls == TypeCache.Double) { return(zeroRes); } return(PythonCalls.Call(cls, zeroRes)); } // integer value is too big, no way we're fitting this in. throw HexStringOverflow(); } // update the bits to truly reflect the exponent if (exponentVal > 0) { finalBits = finalBits << exponentVal; } else if (exponentVal < 0) { decimalPointBit -= exponentVal; } } if ((!exponent.Success && !fraction.Success && !integer.Success) || (!integer.Success && fraction.Length == 1)) { throw PythonOps.ValueError("invalid hexidecimal floating point string '{0}'", self); } if (finalBits == BigInteger.Zero) { if (isNegative) { return(NegativeZero); } else { return(PositiveZero); } } int highBit = finalBits.GetBitCount(); // minus 1 because we'll discard the high bit as it's implicit int finalExponent = highBit - decimalPointBit - 1; while (finalExponent < -1023) { // if we have a number with a very negative exponent // we'll throw away all of the insignificant bits even // if it takes the number down to zero. highBit++; finalExponent++; } if (finalExponent == -1023) { // the exponent bits will be all zero, we're going to be a denormalized number, so // we need to keep the most significant bit. highBit++; } // we have 52 bits to store the exponent. In a normalized number the mantissa has an // implied 1 bit, in denormalized mode it doesn't. int lostBits = highBit - 53; bool rounded = false; if (lostBits > 0) { // we have more bits then we can stick in the double, we need to truncate or round the value. BigInteger finalBitsAndRoundingBit = finalBits >> (lostBits - 1); // check if we need to round up (round half even aka bankers rounding) if ((finalBitsAndRoundingBit & BigInteger.One) != BigInteger.Zero) { // grab the bits we need and the least significant bit which we care about for rounding BigInteger discardedBits = finalBits & ((BigInteger.One << (lostBits - 1)) - 1); if (discardedBits != BigInteger.Zero || // not exactly .5 ((finalBits >> lostBits) & BigInteger.One) != BigInteger.Zero) // or we're exactly .5 and odd and need to round up // round the value up by adding 1 { BigInteger roundedBits = finalBitsAndRoundingBit + 1; // now remove the least significant bit we kept for rounding finalBits = (roundedBits >> 1) & 0xfffffffffffff; // check to see if we overflowed into the next bit (e.g. we had a pattern like ffffff rounding to 1000000) if (roundedBits.GetBitCount() != finalBitsAndRoundingBit.GetBitCount()) { if (finalExponent != -1023) { // we overflowed and we're a normalized number. Discard the new least significant bit so we have // the correct number of bits. We need to raise the exponent to account for this division by 2. finalBits = finalBits >> 1; finalExponent++; } else if (finalBits == BigInteger.Zero) { // we overflowed and we're a denormalized number == 0. Increase the exponent making us a normalized // number. Don't adjust the bits because we're now gaining an implicit 1 bit. finalExponent++; } } rounded = true; } } } if (!rounded) { // no rounding is necessary, just shift the bits to get the mantissa finalBits = (finalBits >> (highBit - 53)) & 0xfffffffffffff; } if (finalExponent > 1023) { throw HexStringOverflow(); } // finally assemble the bits long bits = (long)finalBits; bits |= (((long)finalExponent) + 1023) << 52; if (isNegative) { bits |= unchecked ((long)0x8000000000000000); } double res = BitConverter.Int64BitsToDouble(bits); if (cls == TypeCache.Double) { return(res); } return(PythonCalls.Call(cls, res)); }
/// <summary> /// Returns the digits for the format spec, no sign is included. /// </summary> private static string DoubleToFormatString(CodeContext /*!*/ context, double self, StringFormatSpec /*!*/ spec) { self = Math.Abs(self); const int DefaultPrecision = 6; int precision = spec.Precision ?? DefaultPrecision; string digits; switch (spec.Type) { case '%': { string fmt = "0." + new string('0', precision) + "%"; if (spec.ThousandsComma) { fmt = "#," + fmt; } digits = self.ToString(fmt, CultureInfo.InvariantCulture); break; } case 'f': case 'F': { string fmt = "0." + new string('0', precision); if (spec.ThousandsComma) { fmt = "#," + fmt; } digits = self.ToString(fmt, CultureInfo.InvariantCulture); break; } case 'e': case 'E': { string fmt = "0." + new string('0', precision) + spec.Type + "+00"; if (spec.ThousandsComma) { fmt = "#," + fmt; } digits = self.ToString(fmt, CultureInfo.InvariantCulture); break; } case '\0': case null: if (spec.Precision != null) { // precision applies to the combined digits before and after the decimal point // so we first need find out how many digits we have before... int digitCnt = 1; double cur = self; while (cur >= 10) { cur /= 10; digitCnt++; } // Use exponents if we don't have enough room for all the digits before. If we // only have as single digit avoid exponents. if (digitCnt > spec.Precision.Value && digitCnt != 1) { // first round off the decimal value self = MathUtils.RoundAwayFromZero(self, 0); // then remove any insignificant digits double pow = Math.Pow(10, digitCnt - Math.Max(spec.Precision.Value, 1)); self = self - (self % pow); // finally format w/ the requested precision string fmt = "0.0" + new string('#', spec.Precision.Value); digits = self.ToString(fmt + "e+00", CultureInfo.InvariantCulture); } else { // we're including all the numbers to the right of the decimal we can, we explicitly // round to match CPython's behavior int decimalPoints = Math.Max(spec.Precision.Value - digitCnt, 0); self = MathUtils.RoundAwayFromZero(self, decimalPoints); digits = self.ToString("0.0" + new string('#', decimalPoints)); } } else { // just the default formatting if (IncludeExponent(self)) { digits = self.ToString("0.#e+00", CultureInfo.InvariantCulture); } else if (spec.ThousandsComma) { digits = self.ToString("#,0.0###", CultureInfo.InvariantCulture); } else { digits = self.ToString("0.0###", CultureInfo.InvariantCulture); } } break; case 'n': case 'g': case 'G': { // precision applies to the combined digits before and after the decimal point // so we first need find out how many digits we have before... int digitCnt = 1; double cur = self; while (cur >= 10) { cur /= 10; digitCnt++; } // Use exponents if we don't have enough room for all the digits before. If we // only have as single digit avoid exponents. if (digitCnt > precision && digitCnt != 1) { // first round off the decimal value self = MathUtils.RoundAwayFromZero(self, 0); // then remove any insignificant digits double pow = Math.Pow(10, digitCnt - Math.Max(precision, 1)); double rest = self / pow; self = self - self % pow; if ((rest % 1) >= .5) { // round up self += pow; } string fmt; if (spec.Type == 'n' && context.LanguageContext.NumericCulture != PythonContext.CCulture) { // we've already figured out, we don't have any digits for decimal points, so just format as a number + exponent fmt = "0"; } else if (spec.Precision > 1 || digitCnt > 6) { // include the requested precision to the right of the decimal fmt = "0.#" + new string('#', precision); } else { // zero precision, no decimal fmt = "0"; } if (spec.ThousandsComma) { fmt = "#," + fmt; } digits = self.ToString(fmt + (spec.Type == 'G' ? "E+00" : "e+00"), CultureInfo.InvariantCulture); } else { // we're including all the numbers to the right of the decimal we can, we explicitly // round to match CPython's behavior if (self < 1) { // no implicit 0 digitCnt--; } int decimalPoints = Math.Max(precision - digitCnt, 0); self = MathUtils.RoundAwayFromZero(self, decimalPoints); if (spec.Type == 'n' && context.LanguageContext.NumericCulture != PythonContext.CCulture) { if (digitCnt != precision && (self % 1) != 0) { digits = self.ToString("#,0.0" + new string('#', decimalPoints)); } else { // leave out the decimal if the precision == # of digits or we have a whole number digits = self.ToString("#,0"); } } else { if (digitCnt != precision && (self % 1) != 0) { digits = self.ToString("0.0" + new string('#', decimalPoints)); } else { // leave out the decimal if the precision == # of digits or we have a whole number digits = self.ToString("0"); } } } } break; default: throw PythonOps.ValueError("Unknown format code '{0}' for object of type 'float'", spec.Type.ToString()); } return(digits); }
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())); }
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)); }
internal static List <byte> /*!*/ FromHex(string /*!*/ @string) { if (@string == null) { throw PythonOps.TypeError("expected str, got NoneType"); } List <byte> res = new List <byte>(); for (int i = 0; i < @string.Length; i++) { char c = @string[i]; int iVal = 0; if (Char.IsDigit(c)) { iVal = (c - '0') * 16; } else if (c >= 'A' && c <= 'F') { iVal = (c - 'A' + 10) * 16; } else if (c >= 'a' && c <= 'f') { iVal = (c - 'a' + 10) * 16; } else if (c == ' ') { continue; } else { throw PythonOps.ValueError("non-hexadecimal number found in fromhex() arg at position {0}", i); } i++; if (i == @string.Length) { throw PythonOps.ValueError("non-hexadecimal number found in fromhex() arg at position {0}", i - 1); } c = @string[i]; if (Char.IsDigit(c)) { iVal += c - '0'; } else if (c >= 'A' && c <= 'F') { iVal += c - 'A' + 10; } else if (c >= 'a' && c <= 'f') { iVal += c - 'a' + 10; } else { throw PythonOps.ValueError("non-hexadecimal number found in fromhex() arg at position {0}", i); } res.Add((byte)iVal); } return(res); }
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 BigInteger op_RightShift(BigInteger x, int y) { if (y < 0) { throw PythonOps.ValueError("negative shift count"); } return x >> y; }