convert 0.5 to 0.50 in C# - 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.

Related

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());

Make TryParse compatible with comma or dot decimal separator

The problem:
Let's assume you are using a dot "." as a decimal separator in your regional setting and have coded a string with a comma.
string str = "2,5";
What happens when you decimal.TryParse(str, out somevariable); it?
somevariable will assume 0.
What can you do to solve it?
1-
You can
decimal.TryParse(str, NumberStyles.Any, CultureInfo.InvariantCulture, out somevariable);
And it will return 25, and not 2.5 which is wrong.
2-
You can
decimal.TryParse(str.Replace(",","."), out num);
And it will return the proper value, BUT, if the user uses "," as a decimal separator it will not work.
Possible solution that I can't make it work:
Get the user decimal separator in regional settings:
char sepdec = Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
And make somehow the replace from ",",sepdec , that way it would stay a comma if its a comma, and replace by an actual dot if the user uses dots.
Hints?
Edit: Many users posted useful information, lately, using the arguments NumberStyles.Any, CultureInfo.GetCultureInfo("pt-PT") on a tryParse wouldn't work if your separator is set to "," So it pretty much doesnt fullfill the premise of making a tryparse "universal".
I'll work around this, if anyone has more hints you'r welcome
I know the thread is a little bit older, but I try to provide an answer.
I use regular expression to determine the used number format in the string.
The regex also matches numbers without decimal separators ("12345").
var numberString = "1,234.56"; // en
// var numberString = "1.234,56"; // de
var cultureInfo = CultureInfo.InvariantCulture;
// if the first regex matches, the number string is in us culture
if (Regex.IsMatch(numberString, #"^(:?[\d,]+\.)*\d+$"))
{
cultureInfo = new CultureInfo("en-US");
}
// if the second regex matches, the number string is in de culture
else if (Regex.IsMatch(numberString, #"^(:?[\d.]+,)*\d+$"))
{
cultureInfo = new CultureInfo("de-DE");
}
NumberStyles styles = NumberStyles.Number;
bool isDouble = double.TryParse(numberString, styles, cultureInfo, out number);
HTH
Thomas
I just want to say that HTH Thomas solution worked really well in my project, except for when trying to parse negative decimal numbers with commas. One solution to this, which is probably not optimized because I don't fully understand the regex Ismatch code, but that works is adding the possibility of finding a "-" before the number in the ifs statements, like this:
var cultureInfo = CultureInfo.InvariantCulture;
if (Regex.IsMatch(equation.inputFieldsTexts[i], #"^(:?[\d,]+\.)*\d+$") || Regex.IsMatch(equation.inputFieldsTexts[i], #"^(:?[-\d,]+\.)*\d+$"))
{
cultureInfo = new CultureInfo("en-US");
}
// if the second regex matches, the number string is in DE culture
if (Regex.IsMatch(equation.inputFieldsTexts[i], #"^(:?[\d.]+,)*\d+$") || Regex.IsMatch(equation.inputFieldsTexts[i], #"^(:?[-\d.]+,)*\d+$"))
{
cultureInfo = new CultureInfo("de-DE");
}
The solution I use is to simply show the user what the parsed value is.
I have a custom TextBox control which verifies the input when the control loses focus and such. If the control expects a floating point value (which is a property), then it will try to parse the value entered. If the TryParse succeeds, I display the out value in the control's text.
This way, when a user enters 12.3 the value might change to 123 because in the current culture 12,3 is expected. It's then up to them to decide to correct this.
How about this method:
clean the string from anything else than numbers, dot, comma and negative sign
take the last index of dot or comma
split the clean string and remove all thousands separators from the first part
convert both parts to integer
change the sign of the second part if necessary
add the first part with the second part divided by decimal places
public static bool TryParseDoubleUniversal(this string s, out double result) {
result = 0.0;
if (string.IsNullOrEmpty(s)) return false;
var clean = new string(s.Where(x => char.IsDigit(x) || x == '.' || x == ',' || x == '-').ToArray());
var iOfSep = clean.LastIndexOfAny(new[] { ',', '.' });
var partA = clean.Substring(0, iOfSep).Replace(",", string.Empty).Replace(".", string.Empty);
var partB = clean.Substring(iOfSep + 1);
if (!int.TryParse(partA, out var intA)) return false;
if (!int.TryParse(partB, out var intB)) return false;
if (intA < 0) intB *= -1;
var dp = double.Parse("1".PadRight(partB.Length + 1, '0'));
result = intA + intB / dp;
return true;
}
The question is old but since it was my first hit on Google. And the approach in How to change symbol for decimal point in double.ToString()? seems to be a valid solution you can use the NumberFormatInfo to set the decimal separator like this:
string value = "3,2";
NumberFormatInfo nfi = new NumberFormatInfo();
nfi.NumberDecimalSeparator = ",";
decimal.TryParse(value, NumberStyles.Any, nfi, out decimal dec);
I found a solution, I'm a beginner on this regional and comma-dots theme so if you have comments to improve the understanding of this please be welcome.
We start of by getting what decimal separator the user has set in his regional options outside before the Form{InitializeComponent();} (I want a universal variable that will allow me to correct the code)
char sepdec = Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
In the tryParse, to get it to behave universally we will read the dots and commas in the string, and turn them into the decimal separator we defined as sepdec
decimal.TryParse(str.Replace(",",sepdec.ToString()).Replace(".",sepdec.ToString()), out somevariable);
I hope this helps, please comment improvement suggestions!
In Android Xamarin, I ran into the same issue several times. Some solutions worked until the Android got upgraded into a new version, then the problem came out again. So I came with an universal solution, which works fine. I read the numeric input as text, then parse it into decimal with a custom parser.
The custom parser is returning 0 when parsing into decimal is not possible. It does allow input text containing decimal number with either comma or dot, with no group separators:
public static decimal ParseTextToDecimal(string decimalText)
{
if (decimalText == String.Empty) return 0;
string temp = decimalText.Replace(',', '.');
var decText = temp.Split('.');
if (!Int32.TryParse(decText[0], out int integerPart)) return 0;
if (decText.Length == 1) return integerPart;
if (decText.Length == 2)
{
if (!Int32.TryParse(decText[1], out int decimalPart)) return 0;
decimal powerOfTen = 10m;
for (int i = 1; i < decText[1].Length; i++) powerOfTen *= 10;
return integerPart + decimalPart / powerOfTen;
}
return 0; // there were two or more decimal separators, which is a clear invalid input
}

Double to string with mandatory decimal point

This is probably dumb but it's giving me a hard time. I need to convert/format a double to string with a mandatory decimal point.
1 => 1.0
0.2423423 => 0.2423423
0.1 => 0.1
1234 => 1234.0
Basically, I want to output all decimals but also make sure the rounded values have the redundant .0 too. I am sure there is a simple way to achieve this.
Use double.ToString("N1"):
double d1 = 1d;
double d2 = 0.2423423d;
double d3 = 0.1d;
double d4 = 1234d;
Console.WriteLine(d1.ToString("N1"));
Console.WriteLine(d2.ToString("N1"));
Console.WriteLine(d3.ToString("N1"));
Console.WriteLine(d4.ToString("N1"));
Demo
Standard Numeric Format Strings
The Numeric ("N") Format Specifier
Update
(1.234).ToString("N1") produces 1.2 and in addition to removing additional decimal digits, it also adds a thousands separator
Well, perhaps you need to implement a custom NumberFormatInfo object which you can derive from the current CultureInfo and use in double.ToString:
var culture = CultureInfo.CurrentCulture;
var customNfi = (NumberFormatInfo)culture.NumberFormat.Clone();
customNfi.NumberDecimalDigits = 1;
customNfi.NumberGroupSeparator = "";
Console.WriteLine(d1.ToString(customNfi));
Note that you need to clone it since it's readonly by default.
Demo
There is not a built in method to append a mandatory .0 to the end of whole numbers with the .ToString() method, as the existing formats will truncate or round based on the number of decimal places you specify.
My suggestion is to just roll your own implementation with an extension method
public static String ToDecmialString(this double source)
{
if ((source % 1) == 0)
return source.ToString("f1");
else
return source.ToString();
}
And the usage:
double d1 = 1;
double d2 = 0.2423423;
double d3 = 0.1;
double d4 = 1234;
Console.WriteLine(d1.ToDecimalString());
Console.WriteLine(d2.ToDecimalString());
Console.WriteLine(d3.ToDecimalString());
Console.WriteLine(d4.ToDecimalString());
Results in this output:
1.0
0.2423423
0.1
1234.0
You could do something like this: if the number doesn't have decimal points you can format its output to enforce one decimal 0 and if it has decimal places, just use ToString();
double a1 = 1;
double a2 = 0.2423423;
string result = string.Empty;
if(a1 - Math.Floor(a1) >0.0)
result = a1.ToString();
else
result = a1.ToString("F1");
if (a2 - Math.Floor(a2) > 0.0)
result = a2.ToString();
else
result = a2.ToString("F1");
When you use "F" as formatting, the output won't contain thousands separator and the number that follows it specifies the number of decimal places.
Use ToString("0.0###########################").
It does work. I found it in duplicate of your question decimal ToString formatting which gives at least 1 digit, no upper limit
Double provides a method ToString() where you can pass an IFormatProvider-object stating how you want your double to be converted.
Additionally, it should display trailing 0 at all costs.
value = 16034.125E21;
// Display value using the invariant culture.
Console.WriteLine(value.ToString(CultureInfo.InvariantCulture));
// Display value using the en-GB culture.
Console.WriteLine(value.ToString(CultureInfo.CreateSpecificCulture("en-GB")));
// Display value using the de-DE culture.
Console.WriteLine(value.ToString(CultureInfo.CreateSpecificCulture("de-DE")));
// This example displays the following output to the console:
// -16325.62015
// -16325.62015
// -16325,62015
// 1.6034125E+25
// 1.6034125E+25
// 1,6034125E+25
Here is the documentation from MSDN.
You can cast to string and then appen ".0" if there was no decimal point given
string sValue=doubleValue.ToString();
if(!sValue.Contains('.'))
sValue+=".0";
EDIT:
As mentioned in the comments '.' may not be the decimal seperator in the current culture. Refer to this article to retrieve the actual seperator if you want make your code save for this case.

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
}

C# Double - ToString() formatting with two decimal places but no rounding

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);

Categories