I want a price to be a decimal and for the decimal-sign to be localised. Depending on culture, a decimal may use , or ..
For now I am doing this:
subItem.price.ToString("#.#", CultureInfo.InvariantCulture);
But if the price is 0 (with no decimal point), the result of that turns out to be "" and that makes my system crash.
Is there a better pattern than "#.#" that might handle the 0 in a better way?
How about using "0" custom format specifier instead?
Console.WriteLine((0).ToString("0.0", CultureInfo.InvariantCulture));
prints
0.0
Your code returns empty string because from The "#" custom format specifier
Replaces the "#" symbol with the corresponding digit if one is
present; otherwise, no digit appears in the result string.
Note that this specifier never displays a zero that is not a
significant digit, even if zero is the only digit in the string. It
will display zero only if it is a significant digit in the number that
is being displayed.
By the way your title and your question says different things. Your question doesn't relevant with what number decimal separator is used when you format your value. It is all about why you get empty string when you format your 0 value.
Try 0.#. Will display 0 if value is 0.0
Possibly try using:
subItem.price.ToString("{0:C}", CultureInfo.InvariantCulture);
it formats your string as a currency.
Related
Why is it when I'm parsing a decimal (0) ToString my string shows as empty when using the method:
String somthing = someDecimal.ToString("#")
And when I'm using:
String somthing = somDecimal.ToString("0.##")
The string shows up as 0?
When I'm looking at the value in the debug mode in both way it's says they have a "0" in them.
From The "#" Custom Specifier
Note that this specifier never displays a zero that is not a
significant digit, even if zero is the only digit in the string. It
will display zero only if it is a significant digit in the number that
is being displayed.
If you want to display digits after your decimal point, you need to use 0.00 instead of 0.##.
Because pound "#" means convert to symbol if there is a number. 0 is an "empty" number, so it converts to "".
In fact, in second case, you get 0, as you imply to show at least one digit before dot.
This all is by design convention of C# language.
MSDN: the "#" Custom Specifier
The "#" custom format specifier serves as a digit-placeholder symbol.
If the value that is being formatted has a digit in the position where
the "#" symbol appears in the format string, that digit is copied to
the result string. Otherwise, nothing is stored in that position in
the result string. Note that this specifier never displays a zero that
is not a significant digit, even if zero is the only digit in the
string. It will display zero only if it is a significant digit in the
number that is being displayed.
So if the decimal would be 1 instead of 0 it would be diplayed even with ToString("#").
If you want a fixed number of decimals after the decimal point, you need to use
String somthing = somDecimal.ToString("0.00")
In your example you use the # specifier which means 'put here a number if there is a meaningful number'.
It would work if someDecimal is 0.01
decimal somDecimal = 0.01m
String somthing = somDecimal.ToString("0.##");
but not if
decimal somDecimal = 0.01m
String somthing = somDecimal.ToString("0.#");
So always add a comma and have it to two decimal places, "F" nearly works but can't find the right solution
decimal = 1000.5
test.Text = decimal.ToString("F")
I've also tried:
String.Format("{0:#,###.##}", decimal);
I want to display as the string as 1,000.50
Try:
String.Format("{0:#,###.00}", decimalNumber);
See: Custom Numeric Format Strings
0 - Zero placeholder Replaces the zero with the corresponding digit if
one is present; otherwise, zero appears in the result string. More
information: The "0" Custom Specifier.
It is not going to round the numbers, it is just string formatting.
For culture insensitive formatting do:
String.Format(CultureInfo.InvariantCulture, "{0:#,###.00}", decimalNmber);
String.Format(CultureInfo.InvariantCulture, "{0:0,0.00}", decimal)
For more options see this link.
And here you can test this online.
I have a line like the following in my code:
string buffer = string.Format(CultureInfo.InvariantCulture, "{0:N4}", 1008.0);
Why does buffer contain 1,008.0 (note comma) after executing this line?
Yes, I do guess that it's caused by my regional settings. The question is why they affect the result in this case?
EDIT:
Ok, I understand that it's completely my fault. It seems like I should have used F format specifier.
The InvariantCulture is loosely based on en-US which uses , as a thousands (group) separator.
Your result is what I would expect.
I also point you to the details of the N numeric format specifier:
The numeric ("N") format specifier converts a number to a string of the form "-d,ddd,ddd.ddd…", where "-" indicates a negative number symbol if required, "d" indicates a digit (0-9), "," indicates a group separator, and "." indicates a decimal point symbol.
You're using the invariant culture; your culture is irrelevant to this. For this, the N4 format means
-d,ddd,ddd,ddd...
That is, possible leading negative sign indicator and commas between thousands groups. For details see: http://msdn.microsoft.com/en-us/library/dwhawy9k#NFormatString
You can look at
NegativeSign
NumberNegativePattern
NumberGroupSizes
NumberGroupSeparator
NumberDecimalSeparator
NumberDecimalDigits
for the invariant culture. If you do, you'll see:
-
1
{ 3 }
,
.
2
You are getting the comma because of "{0:N4}"
n ----- Number with commas for thousands ----- {0:n}
Source:
You will get the comma even without specifying InvariantCulture
Console.WriteLine(string.Format("{0:n4}", 1008.0));
Why does 0.ToString("#.##") return an empty string? Shouldn't it be 0.00 or at least 0?
# in the string format indicate that the value is optional. If you wish to get the output 0.00 you need the following:
0.ToString("0.00");
See here for the custom numeric formats that can be passed to this method.
Because in a format string, the # is used to signify an optional character placeholder; it's only used if needed to represent the number.
If you do this instead: 0.ToString("0.##"); you get: 0
Interestingly, if you do this: 0.ToString("#.0#"); you get: .0
If you want all three digits: 0.ToString("0.00"); produces: 0.00
From the comments to this answer, your argument seems to be,
it should show '0', because why would anyone ever want to see an empty string if the numeric value is 0?
The response is simple: You have the choice how you wish it to be displayed. That's what the custom format strings are for. You have simply chosen the incorrect format string for your needs.
According to the documentation about the Digit Placeholder.
If the value being formatted has a digit in the position where the '#' appears in the format string, then that digit is copied to the result string. Otherwise, nothing is
stored in that position in the result string. This specifier never displays the '0' character if it is not a significant digit, even if '0' is the only digit in the string. It will
display the '0' character if it is a significant digit in the number being displayed. The "##" format string 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 "##" would result in the value 35.
If you want the zero to display use the Zero PlaceHolder
f the value being formatted has a digit in the position where the '0' appears in the format string, then that digit is copied to the result string. The position of the
leftmost '0' before the decimal point and the rightmost '0' 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.
Try this 0.ToString("#,##; #,##;0")
https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings#SectionSeparator
The first section applies to positive values, the second section applies to negative values, and the third section applies to zeros.
Use it like this:
0.ToString("#0.##")
0 after # will ensure to set output value to 0 if the value is 0 else it will display the value.
So 0.0.ToString("#0.##")=0.00 and 10.ToString("#.##")=10.00
Given the following code:
string istanbul = "523";
Convert.ToInt32(istanbul.ToString("00"));
what does it return?
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.
The "0" Custom Specifier
link text
This will not even compile:
string istanbul = 523
You cannot assign a number to a string variable like that. You also did not terminate the statement properly with a ;.
C# is also case sensitive, so istanbul and Istanbul refer to different variables.
To answer the question:
523.ToString("00"); // This will evaluate to the string "523"
Convert.ToInt32("523"); // This will evaluate to the integer 523
Read about custom numeric formatting strings.