[Mono-list] Number style / format stuff

Derek Holden dholden@draper.com
Wed, 25 Jul 2001 15:52:59 -0400


Here's some random notes on number styles and formatting. If anyone knows
anything about this, feel free to chime in. This is mainly just so it's on
record.

All the base types (Int16, Int32, Double, etc) implement IFormattable, and
have a couple Parse and ToString methods. Most of these methods are just
calling main method w/ some defaults, for instance int Parse(string s) is
the same behavior as int Parse (s, NumberStyles.Integer, null).

Now those methods, Parse (string str, NumberStyles style, IFormatProvider
fp) and ToString(string format, IFormatProvider) are where it gets someone
confusing. Let's take a simple one, Int32's ToString() method.

Presumably we have to do something with that IFormatProvider. Classes
implementing this define one method, object GetFormat(Type formatType);

Now, ECMA lists that as returning, "A formatting object of the specified
Type. If no formatting object is available, or formatType is null, it
returns the formatting object for the current culture."

The .NET SDK framework however states it as returning "The format object or
null if the service object is not available."

Assume we call GetFormat, since that's the only thing we can do w/ an
IFormatProvider. So here we are w/ an 'object' which may or may not ever be
null, and may or may not contain something related to number formatting.

In ECMA Int32 documentation for that last ToString method, it states fp as
providing a NumberFormatInfo object which contains our culture specific
formatting information. NumberFormatInfo gives us 3 dozen methods like
GetCurrencySymbol and GetDecimalPointSymbol. If it is null, we have to use
our current culture NumberFormatInfo, whatever that may be.

String format is a once char string such as "c" for Curreny, "x" for hex.

So Our ToString is looking something like this

public string ToString (string format, IFormatProvider fp) {
    if (format is null || not one of the valid ("c", "C", "x", "X", "g",
"G", etc))
        complain;

    if(fp is null)
        get our current culture number formatter;
    else {
        object obj = fp.GetFormat(this Type);

        if(obj is null cause .NET sdk says it can be)
            get our current culture numberformatter
        else(if obj is a 'format info type of object')
            then we got it
        else get our current culture number formatter somehow
    }

    switch format {
        case "c" or "C":
        string s1 = ourNumberFormatter.getCurrencySymbol();
        string s2 = ourNumberFormatter.getCurrencyGroupSizes();
        string s3 = ourNumberFormatter.getCurrencyGroupSeparator();
        string s4 = ourNumberFormatter.getCurrencyDecimalSeparator();

        Compose the string using the above, CurrencyNegativeSymbol |
CurrencyPositiveSymbol, and NumberFormatInfo.CurrencyDecimalDigits;
        case etc:
    }
}

It's nothing difficult, could be done efficiently, just tedious, and 90% is
going to be reusalbe. So I guess we'd have to have some internal class that
handles that stuff. The parsing is a little more delicate since you have to
take into account the System.Globalization.NumberStyles. It seems like a lot
of overhead just to get the number 1 as "1", we'd just have to design it so
the 9/10 cases of it using the current culture info can be done separately
without all the checking

I could be completely wrong in all of this, so if someone knows all this
better please let me know.