Main Site Links Resources Tutorials
News VB Gaming Code Downloads DirectX 7
Contact Webmaster VB Programming Product Reviews DirectX 8
  General Multimedia Articles DirectX 9

Converting precision values with strings
by Pascal vd Heiden.
Applies to:  Visual Basic 5 and Visual Basic 6


Converting a String to and from Single or Double is used in most applications. Or you may want to use it to round/format a value in combination with the Format function. Converting Strings to/from precision values is not easy if you want to do it the right way.

The CSng function can convert String into a Single and the CDbl function from String to Double. However, these functions come with a bug in relation to the Regional Settings of the system. This documentation will describe the problems with CSng and CDbl and how to solve them.

Note: You can also use Val to solve the problems that come with CSng and CDbl but if you need to convert, for example 100 strings, Val is extremely slow !!!

Regional Settings or what?

Regional Settings are used by Visual Basic when converting from and to precision values. Regional Settings are different on each system over the world, and so is the conversion of precision values with Strings. This can be usefull when creating an application which has to show the user a value using the Regional Settings, but it can be a pain in the ass if you are transferring precision values (through internet, with files, etc.) from one computer to another.

Creating a String from a precision value is not such a problem, at least, if you like to make use of the Regional Settings…

Dim MyStr as String
Dim MyVal as Single

MyVal = 12.345

MyStr = MyVal

That will do the job (you might want to use CStr for explicit conversion). The String MyStr will now contain a “string-version” of MyVal, but formatted with the Regional Settings’ Currency Symbol. The Currency Symbol is usually a dot for systems configured as English (default), but other countries have other Currency Symbols (comma, for example).


When converting the String back to Single or Double, the use of the Currency Symbol differs in VB5 and VB6. In VB5, the Curreny Sumbol is used, and so your Strings that you want to convert to Single or Double must use that Currency Symbol. Lets take a look what would happen with different Currency Symbols…

DotString = “34.567”
CommaString = “34,567”

DotSingle = CSng(DotString)
CommaSingle = CSng(CommaString)


For Visual Basic 5:

When we use a dot as Currency Symbol, DotSingle will be 34.567 and CommaSingle will be 34567. When we use a comma as Currency Symbol, DotSingle will be 34567 and CommaSingle will be 34.567. This shows that VB5 uses the Regional Settings correctly on the conversions. Lets see what VB6 thinks about this…

For Visual Basic 6:

When we use a dot as Currency Symbol, DotSingle will be 34.567 and CommaSingle will be 34567, just like with VB5. When we use a comma as Currency Sumbol, both DotSingle and CommaSingle will be 34567 ! Visual Basic 6 ignores the Regional Settings and does not use decimals at all, unless the Currency Symbol is a dot !!!

What are you going to do about that?

Nothing. We’ll have to use a “workaround” here. Now you have to choose if you want to make use of the Currency Symbol or not.

When you like to use the Currency Symbol, you can write a DLL in VB5 to do the conversion for your VB6 application, or build your entire application in VB5.

If you don’t like to use the Currency Symbol, or your application doesn’t need it, you can use a small piece of code to change the Currency Symbol temporarely and do your conversion. For fullscreen applications, like games, you can change the Currency Symbol at startup and restore the old symbol at shutdown. For desktop applications, you will have to consider yourself when to change/restore the symbol. (keep in mind that applications in background may not like the Currency Symbol to change while they are doing their conversions using the Currency Symbol !)


Here is some code to receive and/or change the Currency Symbol.

'// API functions needed to get/change the Currency Symbol

'// (note that they each API should be on one line!)

Declare Function GetLocaleInfo Lib "kernel32" Alias "GetLocaleInfoA" (ByVal Locale As Long, ByVal LCType As Long, ByVal lpLCData As String, ByVal cchData As Long) As Long

Declare Function SetLocaleInfo Lib "kernel32" Alias "SetLocaleInfoA" (ByVal Locale As Long, ByVal LCType As Long, ByVal lpLCData As String) As Long

Declare Function GetUserDefaultLCID% Lib "kernel32" ()


'// Constants used

'// Function to get the Currency Symbol from the Regional Settings
Public Function GetCurrencySymbol() As String
Dim Symbol As String
Dim iRet1 As Long
Dim iRet2 As Long
Dim lpLCDataVar As String
Dim Pos As Integer
Dim Locale As Long

   '// Get the Local ID
Locale = GetUserDefaultLCID()

   '// Get the Local info
iRet1 = GetLocaleInfo(Locale, LOCALE_SDECIMAL, lpLCDataVar, 0)


   '// Get the symbol from the Local info
Symbol = String$(iRet1, 0)
iRet2 = GetLocaleInfo(Locale, LOCALE_SDECIMAL, Symbol, iRet1)
Pos = InStr(Symbol, Chr$(0))
If Pos > 0 Then Symbol = left$(Symbol, Pos - 1)


   '// Return the symbol
GetCurrencySymbol = Symbol

End Function



'// Procedure to change the Currency Symbol
Public Sub SetCurrencySymbol(Symbol As String)
Dim Locale As Long
Dim iRet1 As Long

   '// Get the Local ID
Locale = GetUserDefaultLCID()

   '// Change the symbol
iRet1 = SetLocaleInfo(Locale, LOCALE_SDECIMAL, Symbol)

End Sub

Place this code in a Module and you can use GetCurrencySymbol and SetCurrencySymbol to receive/change the Currency Symbol.

Documentation by Pascal vd Heiden


MSDN article Q198098 - PRB: CSng/CDbl Not Using Regional Settings…


See also:
MSDN article Q145695 - PRB: Error Converting String to… When Using "%"

MSDN article - Writing International Code in Visual Basic

DirectX 4 VB © 2000 Jack Hoxley. All rights reserved.
Reproduction of this site and it's contents, in whole or in part, is prohibited,
except where explicitly stated otherwise.
Design by Mateo
Contact Webmaster