Saturday, August 8, 2009

Formatting numeric data types in .NET

Recently I was discussing with one of my friend and he informed me that he was breaking his head on creating a utility to format decimals, float and other datatypes. Out of curiosity I asked him how are you doing these, for e.g. displaying a decimal datatype with only two decimal place value. Bang came the reply that he is doing some string manipulation. I was surprised and informed him that he need not take so much of a pain instead he can use ToString methods of most of the datatype to format the data types. In this blog I will highlight some of the commonly needed number formatting techniques.

First up formatting for decimal places.

This is one of the common requirement where we always come across situation to format float, decimal and double datatypes to some number of decimal places. One of the easiest way to format is given below.

double doub = 8457.3299;
float fl = 28398.39843289f;
decimal dec = 982389.348093m;
Console.WriteLine(doub.ToString(".00"));//Output: 8467.33
Console.WriteLine(fl.ToString(".000"));//Output: 28398.400
Console.WriteLine(dec.ToString(".0000"));//Output: 982389.3481

In the above e.g. I have used zero in combination with decimal symbol to format the numbers according to the required precision required. If the need is to format to the max of two decimal places I have used “.” (dot) followed by 2 zeroes. Similarly how many precision points you want you can use that number of zeroes along with dot. Isn’t it so simple? One thing to note here is that the system will automatically round off the numbers if there are more decimal places than what is specified in the format string as you can see in the above e.g.

Formatting numbers

Some number formatting e.g. are given below.

double doub = 8457.3299;
float fl = 28398.39843289f;
decimal dec = 982389.348093m;
Console.WriteLine(doub.ToString("000"));//Ouput 8457
Console.WriteLine(fl.ToString("00000000"));//Ouput 00028398
Console.WriteLine(dec.ToString("00000.000"));//Ouput 982389.348
Console.WriteLine(dec.ToString("00 - 00 - 0.000"));//Ouput 982 - 38 - 9.348
Console.WriteLine(dec.ToString("(00000) (00) (0)"));//Ouput (00982) (38) (9)

In the above e.gs we have used zeroes to format numbers. First formatting using 3 zeroes doesn’t do much. It just displays the numbers as it is. The second one with 8 zeroes formats numbers and adds extra zeroes if the number doesn’t have the required digits i.e. in the above e.g. there are only 5 digits and because of formatting applied it adds extra zeroes preceeding the number. Use of zero to format numbers tells the system that even if zero is not a significant number it should display zero. One can use other characters along with zero to format the numbers. Few e.g. have been highlighted above.

Formatting numbers using # symbol

One of the problem while using 0 to format numbers is that it will show the insignificant numbers or club zeroes to fill the gap. To avoid just this you can make use of # symbol in place of 0. To show the difference between # and 0 I have pasted below same e.g. with both the format string.

double twoDeci = 1234.34;
int flo = 2343243;
decimal deci = 23434355.6749m;
Console.WriteLine(twoDeci.ToString("######.####"));\\Output 1234.34
Console.WriteLine(twoDeci.ToString("000000.0000"));\\Ouput 001234.3400
Console.WriteLine(flo.ToString("(####) - (###) - (##)"));\\Output (23) - (432) - (43)
Console.WriteLine(flo.ToString("(0000) - (000) - (00)"));\\Output (0023) - (432) - (43)
Console.WriteLine(deci.ToString(".##"));\\Output 23434355.67
Console.WriteLine(deci.ToString(".00"));\\Output 23434355.67

From the above e.gs one can make out that if you are using 0 as the format string then it adds insignificant zeroes preceding or leading the numbers, whereas # will ignore insignificant zeroes. Also one thing to note is that if you use # with numbers with insignificant zeroes then it will ignore those zeroes whereas 0 will consider the zeroes as significant. The difference is shown below.

float preecedingZeroes = 00034556;
double leadingZeroes = 34345.983000;
Console.WriteLine(preecedingZeroes.ToString("########"));\\Ouput 34556
Console.WriteLine(preecedingZeroes.ToString("00000000"));\\Ouput 00034556
Console.WriteLine(leadingZeroes.ToString("#####.######"));\\Ouput 34345.983
Console.WriteLine(leadingZeroes.ToString("00000.000000"));\\Ouput 34345.983000

From the above e.g. differences are clear that # never takes into consideration the insignificant zeroes even if there is one in the datatype. So if you want the insignificant zeroes to be considered then you need to use 0 instead of #.

Formatting for thousand separator.

Many a times we get numbers from the database without any formatting applied and we may require the numbers to be formatting with thousand separators. Its very easy to apply thousand separators to a number. E.g. are pasted below.

double preecedingZeroes = 345563434;
Console.WriteLine(preecedingZeroes.ToString("#,#"));\\Output 345,563,434
Console.WriteLine(preecedingZeroes.ToString("0,0"));\\Output 345,563,434

The above e.g. makes use of both # and 0 along with “,” sign for thousand formatting. Comma (,) can be used along with other format strings to apply thousand formatting. One thing to note here is that when you apply thousand separator formatting then the system makes use of the system’ culture and thousand separator associated with the culture. If you want to use a specific culture’ thousand separator then you need to provide the culture you want to use along with the “ToString” method. Here are e.g. in Danish and Indian format.

//Applies Hindi-India culture and formats the number based on Indian notations.
Console.WriteLine(preecedingZeroes.ToString("#,#", System.Globalization.CultureInfo.CreateSpecificCulture("hi-IN")));//Ouput 34,55,63,434
//Applies Danish culture and formats the number based on Danish culture.
Console.WriteLine(preecedingZeroes.ToString("0,0", System.Globalization.CultureInfo.CreateSpecificCulture("da-DK")));//Ouput 345.563.434

So you can see from the above e.g. that in the Indian culture the thousand separator used is comma (,) whereas in Danish culture the thousand separator is represented by a dot (.)

One thing to note here is that if you use “,” one after the other without any number formatting characters in between them, then the meaning of comma completely changes. The system consider each comma as 1000 and divides the number to which formatting is applied by 1000. Confused, let me explain with e.g.

double dou = 23432432423;
Console.WriteLine(dou.ToString("#,,"));//Output 23432
Console.WriteLine(dou.ToString("0,,,"));//Output 23

In the above e.g. if you see in the first formatting we have used two commas which means the number “23432432423” will be divided by thousand two times as the number of commas occur two times in the formatting string. Similarly in the second sample code the commas occur thrice so the number will be divided by 1000 three times.

Formatting for positive and negative numbers.

There may situation where you don’t know what type of number you are getting from the database, whether the number is a positive or a negative one. Even the number can be a zero. You would like to apply different formatting for positive number and different formatting for negative number. Also you would like to show zero in a different way. I have faced a similar prob in one of my projects where the client wanted to display a positive symbol enclosed in brackets (+) in front of a positive number, a negative symbol enclosed in brackets (-) in case of negative numbers and a zero enclosed in brackets (0) in the case of zero. If you also face a similar kind of situation you can make use “;” (semi colon) to separate the formatting. Sample formatting code is given below.

double positiveNo = 3746;
double negativeNo = -3435;
double zero = 0;
string formatString = "(+)#;(-)#;(0)";
Console.WriteLine(positiveNo.ToString(formatString));//Output (+)3746
Console.WriteLine(negativeNo.ToString(formatString));//Output (-)3435
Console.WriteLine(zero.ToString(formatString));//Output (0)

In the above e.g. if you notice I have defined the formatting string for positive, negative and zero in the variable “formatString”. Semi colon (;) is used as the separator for the different number format. This is how this works, starting from left in the formatString variable the format string to the left of the first semi colon is considered as the formatting string for positive numbers, and the format string in between the first semi colon and the second semi colon is considered the format string for negative values and the format string to the right of second semi colon is taken as the format string for zeroes.

If you don’t want to give separate formatting for zero then you can just leave the format string after the second semi colon empty i.e. you need to only specify format strings for positive and negative values. In such situation the format string for positive value will be applied to format zeroes. The sample is given below.

double positiveNo = 3746;
double negativeNo = -3435;
double zero = 0;
string formatString = "(+)#;(-)#";
Console.WriteLine(positiveNo.ToString(formatString));//Output (+)3746
Console.WriteLine(negativeNo.ToString(formatString));//Output (-)3435
Console.WriteLine(zero.ToString(formatString));//Output (+)

Multiplying a number by 100.

If you want to multiply a number by 100 one can make use of the % symbol in the format string along with other format strings. Sample code is pasted below.

double dd = .459;
double ddd = 849;
Console.WriteLine(dd.ToString("#%"));//Output 46%
Console.WriteLine(dd.ToString(".#%"));//Output 45.9%
Console.WriteLine(ddd.ToString("#%"));//Output 84900%
Console.WriteLine(dd.ToString("#.#%"));//Output 45.9%
Console.WriteLine(ddd.ToString("0%"));//Output 84900%

You can see from the above e.g. that by using the % sign along with other format strings the number gets multiplied by 100 and % symbol is appended at the end of the number.

Appending currency symbol to a number.

Another common requirement is to append the currency symbol along with numbers. To do just that one can make use of “C” or “c” character in the format string. The e.g. is given below.

double curFor = 329.5943;
Console.WriteLine(curFor.ToString("C"));//Output $329.59
Console.WriteLine(curFor.ToString("C3"));//Output $329.594

The currency symbol and precision points will be taken from the current culture set for the system. If you want to specify precision points for decimal value then you can specify the number of precision points after the “C” symbol as shown in the above e.g. If you want to change the current culture and apply some other culture then you can do that as shown in the below e.g.

Console.WriteLine(curFor.ToString("C3", System.Globalization.CultureInfo.CreateSpecificCulture("en-GB")));//Output £329.594

In the above e.g. we are using currency format specifier with 3 decimal point precision and also we are applying Great Britain’ i.e. UK’ culture. This formats the number and adds the pound symbol.

Displaying numbers in exponential form

If you want to display numbers in exponential format you can make use of “E” or “e”. Sample code is pasted below.

double exp = 43895.04390;
Console.WriteLine(exp.ToString("e"));//Output 4.389504e+004

If you want you can specify the number of precision decimal points to be displayed. If the precision points are not specified then the system by default will add 6 precision points after the decimal point. Sample code with precision point is pasted below.

double exp = 43895.04390;
Console.WriteLine(exp.ToString("E9"));//Output 4.389504390E+004

So with that I have covered some of the common number formatting requirements.

Try to know more.

Sandeep

3 comments:

  1. FUCKING THANK YOU.

    YOU ARE TEH L337.

    ReplyDelete
  2. in asp.net web page what kind of data type used to store the value
    99999999999999999999999999999999999999

    ReplyDelete

Please provide your valuable comments.