C# Double - ToString() formatting with two decimal places but no rounding - c#
How do I format a Double to a String in C# so as to have only two decimal places?
If I use String.Format("{0:0.00}%", myDoubleValue) the number is then rounded and I want a simple truncate without any rounding. I also want the conversion to String to be culture sensitive.
I use the following:
double x = Math.Truncate(myDoubleValue * 100) / 100;
For instance:
If the number is 50.947563 and you use the following, the following will happen:
- Math.Truncate(50.947563 * 100) / 100;
- Math.Truncate(5094.7563) / 100;
- 5094 / 100
- 50.94
And there's your answer truncated, now to format the string simply do the following:
string s = string.Format("{0:N2}%", x); // No fear of rounding and takes the default number format
The following rounds the numbers, but only shows up to 2 decimal places (removing any trailing zeros), thanks to .##.
decimal d0 = 24.154m;
decimal d1 = 24.155m;
decimal d2 = 24.1m;
decimal d3 = 24.0m;
d0.ToString("0.##"); //24.15
d1.ToString("0.##"); //24.16 (rounded up)
d2.ToString("0.##"); //24.1
d3.ToString("0.##"); //24
http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/
I suggest you truncate first, and then format:
double a = 123.4567;
double aTruncated = Math.Truncate(a * 100) / 100;
CultureInfo ci = new CultureInfo("de-DE");
string s = string.Format(ci, "{0:0.00}%", aTruncated);
Use the constant 100 for 2 digits truncate; use a 1 followed by as many zeros as digits after the decimal point you would like. Use the culture name you need to adjust the formatting result.
i use price.ToString("0.00")
for getting the leading 0s
Simplest method, use numeric format strings:
double total = "43.257"
MessageBox.Show(total.ToString("F"));
The c# function, as expressed by Kyle Rozendo:
string DecimalPlaceNoRounding(double d, int decimalPlaces = 2)
{
double factor = Math.Pow(10, decimalPlaces);
d = d * factor;
d = Math.Truncate(d);
d = d / factor;
return string.Format("{0:N" + Math.Abs(decimalPlaces) + "}", d);
}
How about adding one extra decimal that is to be rounded and then discarded:
var d = 0.241534545765;
var result1 = d.ToString("0.###%");
var result2 = result1.Remove(result1.Length - 1);
I had that problem with Xamarin Forms and solved it with this:
percent.ToString("0.##"+"%")
This is working for me
string prouctPrice = Convert.ToDecimal(String.Format("{0:0.00}", Convert.ToDecimal(yourString))).ToString();
I know this is a old thread but I've just had to do this. While the other approaches here work, I wanted an easy way to be able to affect a lot of calls to string.format. So adding the Math.Truncate to all the calls to wasn't really a good option. Also as some of the formatting is stored in a database, it made it even worse.
Thus, I made a custom format provider which would allow me to add truncation to the formatting string, eg:
string.format(new FormatProvider(), "{0:T}", 1.1299); // 1.12
string.format(new FormatProvider(), "{0:T(3)", 1.12399); // 1.123
string.format(new FormatProvider(), "{0:T(1)0,000.0", 1000.9999); // 1,000.9
The implementation is pretty simple and is easily extendible to other requirements.
public class FormatProvider : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof (ICustomFormatter))
{
return this;
}
return null;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
if (arg == null || arg.GetType() != typeof (double))
{
try
{
return HandleOtherFormats(format, arg);
}
catch (FormatException e)
{
throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
}
}
if (format.StartsWith("T"))
{
int dp = 2;
int idx = 1;
if (format.Length > 1)
{
if (format[1] == '(')
{
int closeIdx = format.IndexOf(')');
if (closeIdx > 0)
{
if (int.TryParse(format.Substring(2, closeIdx - 2), out dp))
{
idx = closeIdx + 1;
}
}
else
{
throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
}
}
}
double mult = Math.Pow(10, dp);
arg = Math.Truncate((double)arg * mult) / mult;
format = format.Substring(idx);
}
try
{
return HandleOtherFormats(format, arg);
}
catch (FormatException e)
{
throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
}
}
private string HandleOtherFormats(string format, object arg)
{
if (arg is IFormattable)
{
return ((IFormattable) arg).ToString(format, CultureInfo.CurrentCulture);
}
return arg != null ? arg.ToString() : String.Empty;
}
}
To what is worth, for showing currency, you can use "C":
double cost = 1.99;
m_CostText.text = cost.ToString("C"); /*C: format as currentcy */
Output: $1.99
You could also write your own IFormatProvider, though I suppose eventually you'd have to think of a way to do the actual truncation.
The .NET Framework also supports custom formatting. This typically involves the creation of a formatting class that implements both IFormatProvider and ICustomFormatter. (msdn)
At least it would be easily reusable.
There is an article about how to implement your own IFormatProvider/ICustomFormatter here at CodeProject. In this case, "extending" an existing numeric format might be the best bet. It doesn't look too hard.
Following can be used for display only which uses the property of String ..
double value = 123.456789;
String.Format("{0:0.00}", value);
Solution:
var d = 0.123345678;
var stringD = d.ToString();
int indexOfP = stringD.IndexOf(".");
var result = stringD.Remove((indexOfP+1)+2);
(indexOfP+1)+2(this number depend on how many number you want to
preserve. I give it two because the question owner want.)
Also note the CultureInformation of your system. Here my solution without rounding.
In this example you just have to define the variable MyValue as double.
As result you get your formatted value in the string variable NewValue.
Note - Also set the C# using statement:
using System.Globalization;
string MyFormat = "0";
if (MyValue.ToString (CultureInfo.InvariantCulture).Contains (CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator))
{
MyFormat += ".00";
}
string NewValue = MyValue.ToString(MyFormat);
Related
Converting to decimal returns the numbers concated [duplicate]
I want to parse a string like "3.5" to a double. However, double.Parse("3.5") yields 35 and double.Parse("3.5", System.Globalization.NumberStyles.AllowDecimalPoint) throws a FormatException. Now my computer's locale is set to German, wherein a comma is used as decimal separator. It might have to do something with that and double.Parse() expecting "3,5" as input, but I'm not sure. How can I parse a string containing a decimal number that may or may not be formatted as specified in my current locale?
double.Parse("3.5", CultureInfo.InvariantCulture)
I usualy use a multi-culture function to parse user input, mostly because if someone is used to the numpad and is using a culture that use a comma as the decimal separator, that person will use the point of the numpad instead of a comma. public static double GetDouble(string value, double defaultValue) { double result; //Try parsing in the current culture if (!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.CurrentCulture, out result) && //Then try in US english !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) && //Then in neutral language !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result)) { result = defaultValue; } return result; } Beware though, #nikie comments are true. To my defense, I use this function in a controlled environment where I know that the culture can either be en-US, en-CA or fr-CA. I use this function because in French, we use the comma as a decimal separator, but anybody who ever worked in finance will always use the decimal separator on the numpad, but this is a point, not a comma. So even in the fr-CA culture, I need to parse number that will have a point as the decimal separator.
I couldn't write a comment, so I write here: double.Parse("3.5", CultureInfo.InvariantCulture) is not a good idea, because in Canada we write 3,5 instead of 3.5 and this function gives us 35 as a result. I tested both on my computer: double.Parse("3.5", CultureInfo.InvariantCulture) --> 3.5 OK double.Parse("3,5", CultureInfo.InvariantCulture) --> 35 not OK This is a correct way that Pierre-Alain Vigeant mentioned public static double GetDouble(string value, double defaultValue) { double result; // Try parsing in the current culture if (!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.CurrentCulture, out result) && // Then try in US english !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) && // Then in neutral language !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result)) { result = defaultValue; } return result; }
Double.Parse("3,5".Replace(',', '.'), CultureInfo.InvariantCulture) Replace the comma with a point before parsing. Useful in countries with a comma as decimal separator. Think about limiting user input (if necessary) to one comma or point.
Look, every answer above that proposes writing a string replacement by a constant string can only be wrong. Why? Because you don't respect the region settings of Windows! Windows assures the user to have the freedom to set whatever separator character s/he wants. S/He can open up the control panel, go into the region panel, click on advanced and change the character at any time. Even during your program run. Think of this. A good solution must be aware of this. So, first you will have to ask yourself, where this number is coming from, that you want to parse. If it's coming from input in the .NET Framework no problem, because it will be in the same format. But maybe it was coming from outside, maybe from a external server, maybe from an old DB that only supports string properties. There, the db admin should have given a rule in which format the numbers are to be stored. If you know for example that it will be an US DB with US format you can use this piece of code: CultureInfo usCulture = new CultureInfo("en-US"); NumberFormatInfo dbNumberFormat = usCulture.NumberFormat; decimal number = decimal.Parse(db.numberString, dbNumberFormat); This will work fine anywhere on the world. And please don't use 'Convert.ToXxxx'. The 'Convert' class is thought only as a base for conversions in any direction. Besides: You may use the similar mechanism for DateTimes too.
The trick is to use invariant culture, to parse dot in all cultures. double.Parse("3.5", System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.NumberFormatInfo.InvariantInfo);
string testString1 = "2,457"; string testString2 = "2.457"; double testNum = 0.5; char decimalSepparator; decimalSepparator = testNum.ToString()[1]; Console.WriteLine(double.Parse(testString1.Replace('.', decimalSepparator).Replace(',', decimalSepparator))); Console.WriteLine(double.Parse(testString2.Replace('.', decimalSepparator).Replace(',', decimalSepparator)));
My two cents on this topic, trying to provide a generic, double conversion method: private static double ParseDouble(object value) { double result; string doubleAsString = value.ToString(); IEnumerable<char> doubleAsCharList = doubleAsString.ToList(); if (doubleAsCharList.Where(ch => ch == '.' || ch == ',').Count() <= 1) { double.TryParse(doubleAsString.Replace(',', '.'), System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result); } else { if (doubleAsCharList.Where(ch => ch == '.').Count() <= 1 && doubleAsCharList.Where(ch => ch == ',').Count() > 1) { double.TryParse(doubleAsString.Replace(",", string.Empty), System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result); } else if (doubleAsCharList.Where(ch => ch == ',').Count() <= 1 && doubleAsCharList.Where(ch => ch == '.').Count() > 1) { double.TryParse(doubleAsString.Replace(".", string.Empty).Replace(',', '.'), System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result); } else { throw new ParsingException($"Error parsing {doubleAsString} as double, try removing thousand separators (if any)"); } } return result; } Works as expected with: 1.1 1,1 1,000,000,000 1.000.000.000 1,000,000,000.99 1.000.000.000,99 5,000,111.3 5.000.111,3 0.99,000,111,88 0,99.000.111.88 No default conversion is implemented, so it would fail trying to parse 1.3,14, 1,3.14 or similar cases.
The following code does the job in any scenario. It's a little bit parsing. List<string> inputs = new List<string>() { "1.234.567,89", "1 234 567,89", "1 234 567.89", "1,234,567.89", "123456789", "1234567,89", "1234567.89", }; string output; foreach (string input in inputs) { // Unify string (no spaces, only .) output = input.Trim().Replace(" ", "").Replace(",", "."); // Split it on points string[] split = output.Split('.'); if (split.Count() > 1) { // Take all parts except last output = string.Join("", split.Take(split.Count()-1).ToArray()); // Combine token parts with last part output = string.Format("{0}.{1}", output, split.Last()); } // Parse double invariant double d = double.Parse(output, CultureInfo.InvariantCulture); Console.WriteLine(d); }
I think 100% correct conversion isn't possible, if the value comes from a user input. e.g. if the value is 123.456, it can be a grouping or it can be a decimal point. If you really need 100% you have to describe your format and throw an exception if it is not correct. But I improved the code of JanW, so we get a little bit more ahead to the 100%. The idea behind is, that if the last separator is a groupSeperator, this would be more an integer type, than a double. The added code is in the first if of GetDouble. void Main() { List<string> inputs = new List<string>() { "1.234.567,89", "1 234 567,89", "1 234 567.89", "1,234,567.89", "1234567,89", "1234567.89", "123456789", "123.456.789", "123,456,789," }; foreach(string input in inputs) { Console.WriteLine(GetDouble(input,0d)); } } public static double GetDouble(string value, double defaultValue) { double result; string output; // Check if last seperator==groupSeperator string groupSep = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator; if (value.LastIndexOf(groupSep) + 4 == value.Count()) { bool tryParse = double.TryParse(value, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, out result); result = tryParse ? result : defaultValue; } else { // Unify string (no spaces, only . ) output = value.Trim().Replace(" ", string.Empty).Replace(",", "."); // Split it on points string[] split = output.Split('.'); if (split.Count() > 1) { // Take all parts except last output = string.Join(string.Empty, split.Take(split.Count()-1).ToArray()); // Combine token parts with last part output = string.Format("{0}.{1}", output, split.Last()); } // Parse double invariant result = double.Parse(output, System.Globalization.CultureInfo.InvariantCulture); } return result; }
var doublePattern = #"(?<integer>[0-9]+)(?:\,|\.)(?<fraction>[0-9]+)"; var sourceDoubleString = "03444,44426"; var match = Regex.Match(sourceDoubleString, doublePattern); var doubleResult = match.Success ? double.Parse(match.Groups["integer"].Value) + (match.Groups["fraction"].Value == null ? 0 : double.Parse(match.Groups["fraction"].Value) / Math.Pow(10, match.Groups["fraction"].Value.Length)): 0; Console.WriteLine("Double of string '{0}' is {1}", sourceDoubleString, doubleResult);
Instead of having to specify a locale in all parses, I prefer to set an application wide locale, although if string formats are not consistent across the app, this might not work. CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("pt-PT"); CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("pt-PT"); Defining this at the begining of your application will make all double parses expect a comma as the decimal delimiter. You can set an appropriate locale so that the decimal and thousands separator fits the strings you are parsing.
It's difficult without specifying what decimal separator to look for, but if you do, this is what I'm using: public static double Parse(string str, char decimalSep) { string s = GetInvariantParseString(str, decimalSep); return double.Parse(s, System.Globalization.CultureInfo.InvariantCulture); } public static bool TryParse(string str, char decimalSep, out double result) { // NumberStyles.Float | NumberStyles.AllowThousands got from Reflector return double.TryParse(GetInvariantParseString(str, decimalSep), NumberStyles.Float | NumberStyles.AllowThousands, System.Globalization.CultureInfo.InvariantCulture, out result); } private static string GetInvariantParseString(string str, char decimalSep) { str = str.Replace(" ", ""); if (decimalSep != '.') str = SwapChar(str, decimalSep, '.'); return str; } public static string SwapChar(string value, char from, char to) { if (value == null) throw new ArgumentNullException("value"); StringBuilder builder = new StringBuilder(); foreach (var item in value) { char c = item; if (c == from) c = to; else if (c == to) c = from; builder.Append(c); } return builder.ToString(); } private static void ParseTestErr(string p, char p_2) { double res; bool b = TryParse(p, p_2, out res); if (b) throw new Exception(); } private static void ParseTest(double p, string p_2, char p_3) { double d = Parse(p_2, p_3); if (d != p) throw new Exception(); } static void Main(string[] args) { ParseTest(100100100.100, "100.100.100,100", ','); ParseTest(100100100.100, "100,100,100.100", '.'); ParseTest(100100100100, "100.100.100.100", ','); ParseTest(100100100100, "100,100,100,100", '.'); ParseTestErr("100,100,100,100", ','); ParseTestErr("100.100.100.100", '.'); ParseTest(100100100100, "100 100 100 100.0", '.'); ParseTest(100100100.100, "100 100 100.100", '.'); ParseTest(100100100.100, "100 100 100,100", ','); ParseTest(100100100100, "100 100 100,100", '.'); ParseTest(1234567.89, "1.234.567,89", ','); ParseTest(1234567.89, "1 234 567,89", ','); ParseTest(1234567.89, "1 234 567.89", '.'); ParseTest(1234567.89, "1,234,567.89", '.'); ParseTest(1234567.89, "1234567,89", ','); ParseTest(1234567.89, "1234567.89", '.'); ParseTest(123456789, "123456789", '.'); ParseTest(123456789, "123456789", ','); ParseTest(123456789, "123.456.789", ','); ParseTest(1234567890, "1.234.567.890", ','); } This should work with any culture. It correctly fails to parse strings that has more than one decimal separator, unlike implementations that replace instead of swap.
I improved the code of #JanW as well... I need it to format results from medical instruments, and they also send ">1000", "23.3e02", "350E-02", and "NEGATIVE". private string FormatResult(string vResult) { string output; string input = vResult; // Unify string (no spaces, only .) output = input.Trim().Replace(" ", "").Replace(",", "."); // Split it on points string[] split = output.Split('.'); if (split.Count() > 1) { // Take all parts except last output = string.Join("", split.Take(split.Count() - 1).ToArray()); // Combine token parts with last part output = string.Format("{0}.{1}", output, split.Last()); } string sfirst = output.Substring(0, 1); try { if (sfirst == "<" || sfirst == ">") { output = output.Replace(sfirst, ""); double res = Double.Parse(output); return String.Format("{1}{0:0.####}", res, sfirst); } else { double res = Double.Parse(output); return String.Format("{0:0.####}", res); } } catch { return output; } }
Here is a solution that handles any number string that many include commas and periods. This solution is particular for money amounts so only the tenths and hundredths place are expected. Anything more is treated as a whole number. First remove anything that is not a number, comma, period, or negative sign. string stringAmount = Regex.Replace(originalString, #"[^0-9\.\-,]", ""); Then we split up the number into the whole number and decimal number. string[] decimalParsed = Regex.Split(stringAmount, #"(?:\.|,)(?=\d{2}$)"); (This Regex expression selects a comma or period that is two numbers from the end of the string.) Now we take the whole number and strip it of any commas and periods. string wholeAmount = decimalParsed[0].Replace(",", "").Replace(".", ""); if (wholeAmount.IsNullOrEmpty()) wholeAmount = "0"; Now we handle the decimal part, if any. string decimalAmount = "00"; if (decimalParsed.Length == 2) { decimalAmount = decimalParsed[1]; } Finally we can put the whole and decimal together and parse the Double. double amount = $"{wholeAmount}.{decimalAmount}".ToDouble(); This will handle 200,00, 1 000,00 , 1,000 , 1.000,33 , 2,000.000,78 etc.
I am developing a .Net Maui app that runs on Windows, Mac, Android, and iPhone. I have 3 double values that I parse and store using '.' (e.g. "32.5") in all cases: latitude, longitude, and altitude. I happen to have the Android and iPhone set for Spanish and noticed that the Android parsed the '.' string just fine. However, the iPhone refused to parse it correctly unless I substituted ',' for the '.'. Otherwise, the result was always a huge number. Rather than deal with the complications of localization, I came up with a simple solution that takes advantage of the specific limits of my double numbers. case "Lat": waypoint.Lat = ParseDouble(xmlVal, 90); break; case "Lon": waypoint.Lon = ParseDouble(xmlVal, 180); break; case "Alt": waypoint.Alt = ParseDouble(xmlVal, 32000); public static double ParseDouble(string val, double limit) { double result; if (double.TryParse(val, out result)) { if (Math.Abs(result) <= limit) return result; else if (double.TryParse(val.Replace('.', ','), out result)) { if (Math.Abs(result) <= limit) return result; } } return 0; }
System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.CurrentCulture; string _pos = dblstr.Replace(".", ci.NumberFormat.NumberDecimalSeparator).Replace(",", ci.NumberFormat.NumberDecimalSeparator); double _dbl = double.Parse(_pos);
The below is less efficient, but I use this logic. This is valid only if you have two digits after decimal point. double val; if (temp.Text.Split('.').Length > 1) { val = double.Parse(temp.Text.Split('.')[0]); if (temp.Text.Split('.')[1].Length == 1) val += (0.1 * double.Parse(temp.Text.Split('.')[1])); else val += (0.01 * double.Parse(temp.Text.Split('.')[1])); } else val = double.Parse(RR(temp.Text));
Multiply the number and then divide it by what you multiplied it by before. For example, perc = double.Parse("3.555)*1000; result = perc/1000
double.ToString(???) - format to drop digits BEFORE decimal point and show 2 digits AFTER decimal point?
Is it possible to dislay only the cents in an amount using only ToString(), something like 1.99.ToString("SOME FORMAT HERE")? e.g. what if I want 1.99 to be displayed as "1 dollar(s) 99 cents" ($"{ Convert.ToInt32(amount) } dollar(s) { amount.ToString("???") } cents")?
This would work if amount is a double. If amount is string then you wouldn't need ToString() in following line. Note this is assuming a format you listed in your question: string line = string.Concat("$", amount.ToString().Split('.')[0], " dollar(s) ", amount.ToString().Split('.')[1].Substring(0,2), " cents");
I don't think you will be able to do this with only the ToString method, so here's another way. You can first get the decimal part by doing this: var decimalPart = yourDouble - (int)yourDouble; Then, you can times the decimal part by 100 and convert the result to an int. var twoDigits = (int)(decimalPart * 100); To convert this to a two digit string, you just pad 0s to the left: var result = twoDigits.ToString().PadLeft(2, '0');
I can not do this using only ToString(), but this is almost what you want :) double d = 15.12; var str = d.ToString("0 dollar(s) .00 cents").Replace(".", string.Empty); Anyway, I suggest you to create an extension method to do this: public static class Extensions { public static string ToFormattedString(this double number) { var integerPart = Convert.ToInt32(number); var decimalPart = Convert.ToInt32((number - integerPart) * 100); return String.Format("{0} dollar(s) {1} cents", integerPart, decimalPart); } } usage: Console.WriteLine(d.ToFormattedString());
Format decimal c# - Keep last zero
I have been searching for this but cannot seem to find the answer. I have the following decimals with the corresponding output that I want from String.Format 100.00 -> 100 100.50 -> 100.50 100.51 -> 100.51 My problem is that I cannot seem to find a format which will keep the 0 on the end of 100.50 as well as remove the 2 zeros from 100. Any help is much appreciated. EDIT For some more clarity. I have variables of type decimal, they are only ever going to be 2 decimal places. Basically I want to display 2 decimal places if they exist or none, I don't want to display one decimal place in the case of 100.50 becoming 100.5
As far as I know, there is no such format. You will have to implement this manually, e.g.: String formatString = Math.Round(myNumber) == myNumber ? "0" : // no decimal places "0.00"; // two decimal places
You can use this: string s = number.ToString("0.00"); if (s.EndsWith("00")) { s = number.ToString("0"); }
Test if your number is an integer, and use according format : string.Format((number % 1) == 0 ? "{0}": "{0:0.00}", number)
Ok, this hurts my eyes, but should give you what you want: string output = string.Format("{0:N2}", amount).Replace(".00", ""); UPDATE: I like Heinzi's answer more.
This approach will achieve the desired result while applying the specified culture: decimal a = 100.05m; decimal b = 100.50m; decimal c = 100.00m; CultureInfo ci = CultureInfo.GetCultureInfo("de-DE"); string sa = String.Format(new CustomFormatter(ci), "{0}", a); // Will output 100,05 string sb = String.Format(new CustomFormatter(ci), "{0}", b); // Will output 100,50 string sc = String.Format(new CustomFormatter(ci), "{0}", c); // Will output 100 You can replace the culture with CultureInfo.CurrentCulture or any other culture to fit your needs. The CustomFormatter class is: public class CustomFormatter : IFormatProvider, ICustomFormatter { public CultureInfo Culture { get; private set; } public CustomFormatter() : this(CultureInfo.CurrentCulture) { } public CustomFormatter(CultureInfo culture) { this.Culture = culture; } public object GetFormat(Type formatType) { if (formatType == typeof(ICustomFormatter)) return this; return null; } public string Format(string format, object arg, IFormatProvider formatProvider) { if (formatProvider.GetType() == this.GetType()) { return string.Format(this.Culture, "{0:0.00}", arg).Replace(this.Culture.NumberFormat.NumberDecimalSeparator + "00", ""); } else { if (arg is IFormattable) return ((IFormattable)arg).ToString(format, this.Culture); else if (arg != null) return arg.ToString(); else return String.Empty; } } }
string without point to decimal
I have this string "45043". How can I convert it to decimal 450.43 (i want to use cultureinfo) tks
string s = "45043"; decimal d = decimal.Parse(s) / 100; (I'm not really sure where CultureInfo comes into it. Do you want to convert the decimal back into a string or something like that?)
You'd have something like: string x = "45043"; double num = Double.Parse(s, CultureInfo.GetCultureInfo("de-DE").NumberFormat); Just replace with the culture you want or derive it dynamically.
Using CultureInfo? You mean using commas in certain cultures and periods in others? How about: var str = "45043"; var strToDecimal = (decimal.Parse(str) / 100).ToString(); var strExplicit = (decimal.Parse(str) / 100).ToString(System.Globalization.CultureInfo.CurrentCulture.NumberFormat); // more explicit version of what's happening above.
To show TryParse and use of CultureInfo string input = "45053"; decimal result; if (decimal.TryParse(input, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, out result)) { result /= 100M; } else { // invalid input, handle in whatever way you deem appropriate }
convert 0.5 to 0.50 in C#
I have a string which holds 0.5. I have to convert in to 0.50. I have tried following ways but nothing works.Please help hdnSliderValue.Value is 0.5,I want workFlow.QualityThresholdScore to be 0.50 workFlow.QualityThresholdScore = Convert.ToDecimal(String.format("{0:d}",hdnSliderValue.Value)); workFlow.QualityThresholdScore = Convert.ToDecimal(String.format("{0:0.00}",hdnSliderValue.Value)); IS there any built in function or will i have to do string handling to accomplish this.
The simplest way probably is to use string conversions: string text = "0.5"; decimal parsed = decimal.Parse(text); string reformatted = parsed.ToString("0.00"); decimal reparsed = decimal.Parse(reformatted); Console.WriteLine(reparsed); // Prints 0.50 That's pretty ugly though :( You certainly could do it by first parsing the original string, then messing around with the internal format of the decimal - but it would be significantly harder. EDIT: Okay, in case it's an i18n issue, here's a console app which should definitely print out 0.50: using System; using System.Globalization; class Test { static void Main() { CultureInfo invariant = CultureInfo.InvariantCulture; string text = "0.5"; decimal parsed = decimal.Parse(text, invariant); string reformatted = parsed.ToString("0.00", invariant); decimal reparsed = decimal.Parse(reformatted, invariant); Console.WriteLine(reparsed.ToString(invariant)); // Prints 0.50 } }
It's ToString("N2"). Edit: Add test code to show how it works decimal a = 0.5m; Console.WriteLine(a); // prints out 0.5 string s = a.ToString("N2"); decimal b = Convert.ToDecimal(s); // prints out 0.50 Console.WriteLine(b);
In numerics, 0.5 == 0.50. A zero doesn't add any information, so if QualityThresholdScore is of a numeric type, you will get 0.5 no matter what. If it is a string, use decimal.ToString("0.00");.
Have you tried workFlow.QualityThresholdScore = Convert.ToDecimal(hdnSliderValue.Value.ToString("N2"));
Stringy version since no-one has suggested it. string pointFive = "0.5"; int decimals = (pointFive.Length-1) - pointFive.IndexOf('.'); if (decimals >= pointFive.Length) pointFive += ".00"; else if (decimals == 1) pointFive += "0"; else if (decimals == 0) pointFive += "00"; Might even be quicker than numeric conversions and formatting functions.