Esempio n. 1
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()));
        }
Esempio n. 2
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));
        }