Formatting a double with decimals C# - c#

Is it possible to format a double, so he doesn't chance the text 2140.76 to 214076 but instead letting it be 2140.76?
I can't use ',' for the decimal numbers, since the entire text file that I'm reading are numbers using '.' for separating the decimals, 10000 records, every day, so ...
EDIT:
double natMB = 0;
boolean check = double.TryParse(splitline[8], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out natMB);
if (check == false)
{
natMB = 0;
}
else
{
natMB = natMB * 1024;
}
double intMB = 0;
boolean check2 = double.TryParse(splitline[9], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out intMB);
if (check2==false)
{
intMB=0;
}
else
{
intMB = intMB * 1024;
}
The 0 value is necessary since I need to enter these values in an SQL statement, and they need to show up as 0, not as null.

Your question is not clear, Do you want to parse a double from a string with dot decimal separator ?
If yes try with this :
double.Parse("2140.76", CultureInfo.InvariantCulture)

You can use the invariant culture to format a number with a decimal period, regardless of your local culture settings:
string formatted = someDouble.ToString(CultureInfo.InvariantCulture);

Start reading here:
http://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.aspx
Basically, you create an NumberFormatInfo that you can customise to use with String.Format to use any format you want.

Is it possible to format a double so he doesn't chance the text 2140.76 to 214076 but instead
letting it be 2140.76?
Yes. Let me play ignorant - I have no idea how you can even ask that and have the poroblem given the extensive formatting methods.
I can't use ',' for the decimal numbers, since the entire text file that i'm reading are numbers
using '.' for separating the decimals, 10000 records, every day, so ...
So the problem likely is that you ahve a culture issue at hand and an ignorant developer on the other side. Ignorant because files exchagned should always be english formatted always, to avoid that.
Anyhow, basically:
* Change your culture info in the thread to english or
* Use english culture info for parsing and text generation.
Read the documentation for the methods you use -there areo verlaods that allow you to tune the formatting.

Related

string format money , [duplicate]

I need to display a number with commas and a decimal point.
Eg:
Case 1 : Decimal number is 432324 (This does not have commas or decimal points).
Need to display it as: 432,324.00.
Not: 432,324
Case 2 : Decimal number is 2222222.22 (This does not have commas).
Need to display it as: 2,222,222.22
I tried ToString("#,##0.##"), but it is not formatting it correctly.
int number = 1234567890;
number.ToString("#,##0.00");
You will get the result 1,234,567,890.00.
Maybe you simply want the standard format string "N", as in
number.ToString("N")
It will use thousand separators, and a fixed number of fractional decimals. The symbol for thousands separators and the symbol for the decimal point depend on the format provider (typically CultureInfo) you use, as does the number of decimals (which will normally by 2, as you require).
If the format provider specifies a different number of decimals, and if you don't want to change the format provider, you can give the number of decimals after the N, as in .ToString("N2").
Edit: The sizes of the groups between the commas are governed by the
CultureInfo.CurrentCulture.NumberFormat.NumberGroupSizes
array, given that you don't specify a special format provider.
Try with
ToString("#,##0.00")
From MSDN
*The "0" custom format specifier serves as a zero-placeholder symbol. If the value that is being formatted has a digit in the position where the zero appears in the format string, that digit is copied to the result string; otherwise, a zero appears in the result string. The position of the leftmost zero before the decimal point and the rightmost zero after the decimal point determines the range of digits that are always present in the result string.
The "00" specifier causes the value to be rounded to the nearest digit preceding the decimal, where rounding away from zero is always used. For example, formatting 34.5 with "00" would result in the value 35.*
I had the same problem. I wanted to format numbers like the "General" format in spreadsheets, meaning show decimals if they're significant, but chop them off if not. In other words:
1234.56 => 1,234.56
1234 => 1,234
It needs to support a maximum number of places after the decimal, but don't put trailing zeros or dots if not required, and of course, it needs to be culture friendly. I never really figured out a clean way to do it using String.Format alone, but a combination of String.Format and Regex.Replace with some culture help from NumberFormatInfo.CurrentInfo did the job (LinqPad C# Program).
string FormatNumber<T>(T number, int maxDecimals = 4) {
return Regex.Replace(String.Format("{0:n" + maxDecimals + "}", number),
#"[" + System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator + "]?0+$", "");
}
void Main(){
foreach (var test in new[] { 123, 1234, 1234.56, 123456.789, 1234.56789123 } )
Console.WriteLine(test + " = " + FormatNumber(test));
}
Produces:
123 = 123
1234 = 1,234
1234.56 = 1,234.56
123456.789 = 123,456.789
1234.56789123 = 1,234.5679
Try with
ToString("#,##0.###")
Produces:
1234.55678 => 1,234.556
1234 => 1,234
For Razor View:
$#string.Format("{0:#,0.00}",item.TotalAmount)
CultureInfo us = new CultureInfo("en-US");
TotalAmount.ToString("N", us)
Your question is not very clear but this should achieve what you are trying to do:
decimal numericValue = 3494309432324.00m;
string formatted = numericValue.ToString("#,##0.00");
Then formatted will contain: 3,494,309,432,324.00
All that is needed is "#,0.00", c# does the rest.
Num.ToString("#,0.00"")
The "#,0" formats the thousand separators
"0.00" forces two decimal points
If you are using string variables you can format the string directly using a : then specify the format (e.g. N0, P2, etc).
decimal Number = 2000.55512016465m;
$"{Number:N}" #Outputs 2,000.55512016465
You can also specify the number of decimal places to show by adding a number to the end like
$"{Number:N1}" #Outputs 2,000.5
$"{Number:N2}" #Outputs 2,000.55
$"{Number:N3}" #Outputs 2,000.555
$"{Number:N4}" #Outputs 2,000.5551
string Mynewcurrency = DisplayIndianCurrency("7743450.00");
private string DisplayIndianCurrency(string EXruppesformate)
{
string fare = EXruppesformate;
decimal parsed = decimal.Parse(fare, CultureInfo.InvariantCulture);
CultureInfo hindi = new CultureInfo("en-IN");
// string text = string.Format(hindi, "{0:c}", parsed);if you want <b>Rs 77,43,450.00</b>
string text = string.Format(hindi, "{0:N}", parsed); //if you want <b>77,43,450.00</b>
return ruppesformate = text;
}
For anyone looking at this now, and getting the "No overload for method 'ToString' takes 1 argument" when using:
TotalNumber.ToString("N")
My solution has been to use :
TotalNumber.Value.ToString("N")
I often get stuck on this when working directly inside an MVC View, the following wasn't working:
#Model.Sum(x => x.Number).ToString("N")
Whereas this works:
#Model.Sum(x => x.Number).Value.ToString("N")

Parse String to Decimal using any decimal seperator

I want to parse a string from an Text input to decimal. The value represents a currency value.
Currently i got this solution:
private Decimal CastToDecimal(string value)
{
Decimal result;
var valid = Decimal.TryParse(value, NumberStyles.Currency, null, out result);
return valid ? result : -1;
}
This works pretty well so far, except for possible culture-differences. I'm german and i expect most users to enter german-style puctuation. But it is possible that someone uses "." instead of "," and the conversion will fail.
"123,45€" => 123.45
"123.456,78€" => 123456.78
"123.45€" => 12345 <- I want the result to be 123.45 here
Is there a way to automatically detect the used culture for a decimal value? Such that it does not matter if you use german or english punctuation, you still get the same result?
Update:
Thanks to your help, i created a method which does what i want (i think).
private static Decimal CastToDecimal(string value)
{
Decimal resultDe;
Decimal resultEn;
var style = NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands;
var cultureDe = CultureInfo.CreateSpecificCulture("de-DE");
var cultureEn = CultureInfo.CreateSpecificCulture("en-GB");
var deValid = Decimal.TryParse(value, style, cultureDe, out resultDe);
var enValid = Decimal.TryParse(value, style, cultureEn, out resultEn);
var minVal = Math.Min(resultDe, resultEn);
var maxVal = Math.Max(resultDe, resultEn);
if (!deValid)
return resultEn;
if (!enValid)
return resultDe;
return BitConverter.GetBytes(decimal.GetBits(minVal)[3])[2] > 2 ? maxVal : minVal;
}
This code...
Console.WriteLine(CastToDecimal("123,45"));
Console.WriteLine(CastToDecimal("123.45"));
Console.WriteLine(CastToDecimal("123,450"));
Console.WriteLine(CastToDecimal("123.450"));
Console.WriteLine(CastToDecimal("123.123,45"));
Console.WriteLine(CastToDecimal("123,123.45"));
returns this:
123,45
123,45
123450
123450
123123,45
123123,45
the solution at http://msdn.microsoft.com/en-us/library/3s27fasw%28v=vs.110%29.aspx
which includes setting the NumberStyle may be helpful.
...
value = "1.345,978";
style = NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands;
culture = CultureInfo.CreateSpecificCulture("es-ES");
if (Double.TryParse(value, style, culture, out number))
Console.WriteLine("Converted '{0}' to {1}.", value, number);
else
Console.WriteLine("Unable to convert '{0}'.", value);
// Displays:
// Converted '1.345,978' to 1345.978.
value = "1 345,978";
if (Double.TryParse(value, style, culture, out number))
Console.WriteLine("Converted '{0}' to {1}.", value, number);
else
Console.WriteLine("Unable to convert '{0}'.", value);
...
I encountered the same problem some time ago. My solution was writing my own parser in Java. The algorithm first cleans up the string. Brief description follows:
Scan string from left to right
If char = '.' then dotFound=true ; lastSeparatorPosition = index ; dots++
If char = ',' then commaFound=true ; lastSeparatorPosition = index ; commas++
If dots == 0 && commas == 0 then its an integer => done
If dots > 0 && commas > 0 then the one at lastSeparatorPosition is the decimal separator. Remove the others from the string => done
/* only one separator type */ if ( dots + commas ) > 1 then remove them // because must be thousands separator => done
/* separator occurs once */ if numberOfDigits right of separator == 3 then you have to decide :-) either integer or decimal with 3 digits in fraction
7 is the only remaining problem like chiastic-security already stated. Here you can only decide taken the conceptual environment into account. All other cases are safe.
Have fun
This can't be done, simply because there are strings that are meaningful in two different cultures, but mean different things. For instance:
123.456
123,456
The first is a bit over 123 in the UK, but 123456 in Germany; the second is 123456 in the UK but a bit over 123 in France.
The only solution is to add validation on input and give user and example by the way if it is a webpage then find a way to get input according to user's culture. I suggests you to not to try to do what you are trying because there are some culture which contradict each others for example in currency;
US/Australia/Many others uses following format
45,999.95
where , is thousand separator and . is decimal separator
whereas in some European countries
45.999,95
means the same as above but thousands separator is . and , is used as decimal separator.
Now issue is there is no guarantee that user use both separator and your system may assume thousand separator as decimal and so on.
If you really don't want to bother user then make separate input fields for major and minor currencies.
So its better to not to go there. I believe this may help. Happy Coding :)
Update:
Same case is with date format e.g. in US format month comes first and then day whereas in Australia day comes first and then month now 02/01/2015 input will mean differently system can't tell the intention of user.

How do I programm a language independent double.tryparse?

i got string values representing doubles. (f.e. "1.23"). Always with ".".
If you run the code:
double dDouble =0;
string sDemo ="1.23";
double.TryParse(sDemo,out dDouble));
it will return 1.23 to the dDouble var.
If i switch to a different languge with "," as "." .... i get 123.0 as dDouble.
How do I ensure that its always 1.23 ...
double dDouble =0;
string sDemo ="1.23";
double.TryParse(sDemo,System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out dDouble));
but I am unsure, if this will solve the problem permanently.
i just tried
10 years ago I would solve it like this (do not do that):
sDemo = sDemo.Replace(",",".");
Now
// to string
var text = someDouble.ToString(NumberFormatInfo.InvariantInfo);
// and back
var number = double.Parse(text, NumberFormatInfo.InvariantInfo);
Key point is to use same culture. If you convert values for internal use (to example, passing double value as a part of text) - use invariant culture. If, however, you want to display it to the user and then read user input, then still use same culture: if you don't specify culture for ToString, then don't specify it for Parse, and if you did, then do it again.

How to convert decimal to money format

I'm trying to convert a number so it looks like the formatting in money.
I need to take 258000 and make it 2,580.00 or 25000 and make it 250.00 or 360 and make it 3.60
This is what I'm using but it's adding the ".00" at the end of all numbers making 2500 2500.00 but it should be 25.00.
Value = string.Format("{0:##,###.00}", Convert.ToDecimal(Value));
It seems to me that you're just missing the fact that you can divide the user's input by 100 after parsing it:
using System;
class Program
{
static void Main(string[] args)
{
string input = "2500";
decimal cents = decimal.Parse(input); // Potentially use TryParse...
decimal dollars = cents / 100m;
string output = dollars.ToString("0.00");
Console.WriteLine(output); // 25.00
}
}
Note that there are complicated cultural rules around how currency values should be displayed - I would suggest using the C format specifier, using a CultureInfo which is like whatever the users are expecting, but with the NumberFormatInfo.CurrencySymbol set to an empty string.
You should also consider which culture to use when parsing the user's input - it can significantly affect the results if they decide to use grouping separators or decimal separators. Will they always be entering an integer? If so, parse it as an integer too.
double valueOriginal = 260;
Response.Write( (valueOriginal / 100).ToString("C"));
260 = (206/100)
then
(260/100).ToString("C");

Double.TryParse with a string having two decimal points

This might be a simple and basic question, but, thought of confirming with you. Im in the process of writing code to validate the entered text information is double or not. In my code, below is the line to validate the speed value taken from a text box.
double _mSpeed = 0.0;
if (!Double.TryParse(txtboxSpeed.Text, out _mSpeed))
throw new Exception("Input value for Speed is invalid !!!");
But, if user provides 4.4.4 in speed text box, TryParse is parsing the text string to 444.0 value. Im wondering this is correct or not. Please share your thoughts whether if user enters any value with 2 decimal points, should it not parse to double or what is the expected behavior.
In cultures where . is the decimal separator, like en-US and the invariant culture, 4.4.4 is not valid. In other cultures, like de-DE, , is the decimal separator and . is the thousands separator, so 4.4.4 is 444 (with nonstandard, but acceptable, thousands separators inserted, like 4,4,4 in the en-US culture).
double.Parse("4.4.4", new CultureInfo("de-DE")) // 444
double.Parse("4.4.4", new CultureInfo("en-US")) // FormatException: Input string was not in a correct format.
double.Parse("4,4,4", new CultureInfo("en-US")) // 444
double.Parse("4,4,4", new CultureInfo("de-DE")) // FormatException: Input string was not in a correct format.
The issue could be that the Culture currently used by your application treats comma as decimal separator instead of period. You can force it to use period as decimal separator by setting culture to en-GB.
double _mSpeed = 0.0;
if (!Double.TryParse(txtboxSpeed.Text,NumberStyles.Any,CultureInfo.CreateSpecificCulture("en-GB"), out _mSpeed))
throw new Exception("Input value for Speed is invalid !!!");
Instead of creating a CultureInfo for a specific culture that uses your number format (e.g., "en-US"), you can also just specify NumberFormatInfo.InvariantInfo.
double val1, val2;
bool b1 = double.TryParse("4.4.4", NumberStyles.Any, NumberFormatInfo.InvariantInfo, out val1);
bool b2 = double.TryParse("4,444.4", NumberStyles.Any, NumberFormatInfo.InvariantInfo, out val2);
In the above code b1 is set to false but b2 succeeds and val2 is 4444.4.

Categories