Beispiel #1
0
        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");
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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");
        }
Beispiel #4
0
        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));
        }
Beispiel #5
0
 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);
     }
 }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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()));
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
 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);
     }
 }
Beispiel #11
0
        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));
        }
Beispiel #12
0
        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));
Beispiel #13
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 = 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()));
        }
Beispiel #14
0
 static void ThrowOverflow() => throw PythonOps.OverflowError("int too big to convert");
Beispiel #15
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;

            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));
        }
Beispiel #16
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));
        }
Beispiel #17
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()));
        }
Beispiel #18
0
 private static Exception HexStringOverflow()
 {
     return(PythonOps.OverflowError("hexadecimal value too large to represent as a float"));
 }