String Format

lordofduct

Well-known member
Joined
Jun 24, 2010
Messages
71
Programming Experience
3-5
So I need a format string to pass to String.Format that would "move" the decimal point.

I can't perform any math operations before doing the String.Format, so it has to work right off the bat.

Basically I'm emulating a formatting string from a proprietary server. In it if I say:

"MR2"

for the value:

12345

The result is:

123.45



I'm close with this, but it's not spot on:

String.Format("{0:#0\.##}", 12345)






an extra, but not necessary... there is also MR2Z, which moves the decimal 2 left, but if the value is 0 "" is returned. I don't really need that, but it'd be nice.
 
I said it here:

Basically I'm emulating a formatting string from a proprietary server. In it if I say:

"MR2"

for the value:

12345

The result is:

123.45




and damn it... I just realized I need to figure out a way to 'reverse' them as well... say like if I get:

123.45

I need to convert it back to:

12345

hence one of the main reasons the method I've found so far isn't quite right. I really need a format string that "moves decimal point".





See what it is I'm emulating is that on the proprietary server I use, it's an old operating system that treats all objects as text. Numeric values are stored in either decimal or binary as actual strings. The 'old' versions of it due to low memory would leave out decimal points and instead use these "dict masks" to imply a "fixed point notation" of values. You referred to it when actually displaying values, but treated them as whole integer values when doing math (its the principal behind fixed point notation, if a point is fixed then the point's position if irrelevent when performing arithmetic, most fixed point notations are just stored in integer... for instance like 16.16 fixed point).

Anyways I need to emulate these "fixed point" values arbitrarily through masks to allow for backwards compatability (we can't just go through the server and convert all the stored data to the new method as it would leave our installed user base in the dust)



my only other option is to create my own parsing mask schema, but I'm afraid it will be deathly slow (and cumbersome to write).
 
Last edited:
PHP:
        Dim str As String = "12345"
        str = str.Insert(str.Length - 2, "."c)
        ' if you want to deal with it furhter convert it to decimal or double 
        Dim mydecimal As Decimal = Decimal.Parse(str)
        ' check the value
        MessageBox.Show(mydecimal.ToString)

        ' CONVERT IT BACK
        Dim reversed As String = mydecimal.ToString.Replace("."c, "")
        ' if you want to deal with it furhter convert it to integer 
        Dim converted As Integer = Integer.Parse(reversed)
        ' check the value
        MessageBox.Show(converted.ToString)
 
I need to do it as a IFormatProvider and format string... either through the default Formatter (just passing a format string), or through a custom IFormatProvider (the latter of which I want to avoid because it'll probably be deathly slow).

Or any other method similar.


The premise is this...

a string value is received along with the which attribute on the table it came from
I can then retrieve any "mask" / "format" string as well as a "type" string for converting converting the value
I then have to treat the value as that specific type, and parse the masking string to format the value
then return the value again as a string

The strings can do a marriad of things...

afix trailing decimals
move decimal position
pad
add symbols
etc etc

basically functioning just like the String.Format functions, just with that added "move decimal point" feature (not added if it already exists, but I don't know what it may be).


Of course I could have an extra attribute (fixedpointadjustment) that has the number of spaces to move it... but it would be wonderfully beautiful if I could fit it right into the format string.
 
This was my result, using IFormatProvider... it's ok, but its 4 times slower then a regular format...

VB.NET:
Public Class FixedPointFormatter
    Implements ICustomFormatter
    Implements IFormatProvider

#Region " Custom formatter support "
    Public Function Format(ByVal formatString As String, ByVal arg As Object, ByVal formatProvider As System.IFormatProvider) As String Implements System.ICustomFormatter.Format

        Try
            Dim argNum As Decimal

            If IsNumeric(arg) Then
                argNum = Convert.ToDecimal(arg)
            Else
                argNum = 0
            End If

            If formatString Is Nothing Then Return argNum.ToString()

            ''adjust decimal
            If formatString.StartsWith("p") Then
                Dim arr As String() = formatString.Split(":")
                Dim move As Integer
                Integer.TryParse(arr(0).Substring(1), move)
                argNum /= Math.Pow(10, move)

                If arr.Length > 1 Then
                    Return argNum.ToString(arr(1))
                Else
                    Return argNum.ToString()
                End If

            End If

        Catch ex As Exception
            Return "0"
        End Try

    End Function

#End Region

#Region " Format provider support "

    Public Function GetFormat(ByVal formatType As System.Type) As Object Implements System.IFormatProvider.GetFormat
        If formatType Is GetType(ICustomFormatter) Then
            Return Me
        Else
            Return Nothing
        End If
    End Function

#End Region
End Class


example use:

VB.NET:
Console.WriteLine( New FixedPointFormatter(), "{0:p3:#0.00}", 123456)
'' outputs: 123.46

Console.WriteLine( New FixedPointFormatter(), "{0:p3}", 123456)
'' outputs: 123.456
 
Back
Top