Custom numeric format string to always display the sign
Yes, you can.
There is conditional formatting. See Conditional formatting in MSDN
eg:
string MyString = number.ToString("+0;-#");
Where each section separated by a semicolon represents positive and negative numbers
or:
string MyString = number.ToString("+#;-#;0");
if you don't want the zero to have a plus sign.
Custom numeric format string based on number sign
Any ideas why the formatting is not done correctly ?
Is is done correctly according to the documentation:
If the number to be formatted is negative, but becomes zero after rounding according to the format in the second section, the resulting zero is formatted according to the first section.
Since I don't see any options available that would override that default behavior, one option is to append the parentheses manually:
public string Format(decimal value)
{
string s = (value*100).ToString("0.0;0.0");
if(value < 0)
s = "(" + s + ")";
return s;
}
Format a number to always have a sign and decimal separator
Try something like this:
double x = -12.43;
string xStr = x.ToString("+0.#####;-0.#####");
But this wouldn't help to display trailing decimal point. You can handle such situations using this method:
public static string MyToString(double x)
{
return x == Math.Floor(x)
? x.ToString("+0;-0;0") + CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator
: x.ToString("+0.####;-0.####");
}
double.ToString(string) with custom numeric format string does not produce the expected result
Floating-point numbers are approximations: they have a limited number of bits, and they do their best to represent a number close to the one you asked for within the constraints of the available bits.
Most of the time this works fine, but things start breaking down as you reach the limits of their precision which is around 16 digits for double
and 9 digits for float
.
Specifically, a double cannot represent 63712373026.615219
exactly. With G50
or Jon Skeet's DoubleConverter
, we can take a look at the exact number that the double does represent:
63712373026.615219.ToString("G50"); // 63712373026.6152191162109375
We're fine up to the 7th decimal place, but see how the closest representable number to 63712373026.615219
is actually a little bit larger?
With some trial-and-error, we can see the range of values which all get represented as 63712373026.6152191162109375
:
63712373026.6152230.ToString("G50"); // 63712373026.61522674560546875
63712373026.6152229.ToString("G50"); // 63712373026.6152191162109375
63712373026.615219.ToString("G50"); // 63712373026.6152191162109375
63712373026.6152154.ToString("G50"); // 63712373026.6152191162109375
63712373026.6152153.ToString("G50"); // 63712373026.61521148681640625
The precision limitations of double
mean that everything between 63712373026.6152154
and 63712373026.6152229
gets stored as the number 63712373026.6152191162109375
.
This presents a problem for the formatter: if you asked for 63712373026.615219.ToString("0.000000")
, should it give you 63712373026.615223
or 63712373026.615215
or anything in between?
In practice, what it appears to do is to work out the range of possible values which the double might be representing, and then round to the digits which are common to all. Since 63712373026.6152229
and 63712373026.6152154
and everything in between all start with 63712373026.6152
, that is what the formatter works with. Which is why it will print 63712373026.615200
if you force it to: it knows that it doesn't have enough information to fill in those last 2 digits.
Note that I think the round-trip and G17
formats are misleading you slightly. Round-trip basically prints the fewest digits which will be parsed back into the same underlying double value. So 63712373026.615219
contains the smallest number of decimal places which gets parsed back into 63712373026.6152191162109375
.
Note that they fixed R
on .NET 5:
63712373026.615219.ToString("R"); // 63712373026.61522
G17
just prints 17 digits, regardless of the underlying value of the double. Because double only has around 16 digits of precision, this is also enough to safely round-trip the double.
This can be seen with simpler values, such as 0.1
. double
, not being base 10, can't exactly represent 0.1
. Instead its closest value is:
0.1.ToString("G99"); // 0.1000000000000000055511151231257827021181583404541015625
However:
0.1.ToString("R"); // 0.1
The shortest value which gets represented as 0.1000000000000000055511151231257827021181583404541015625
is 0.1
, so this is what R
returns, even though it doesn't quite match the underlying representation. This is fine, because parsing 0.1
will result in a double whose underlying representation is 0.1000000000000000055511151231257827021181583404541015625
, thus successfully round-tripping it.
How to force a sign when formatting an Int in c#
Try this:
i.ToString("+00;-00;+00");
When separated by a semicolon (;) the first section will apply to positive values, the second section will apply to negative values, the third section will apply to zero (0).
Note that the third section can be omitted if you want zero to be formatted the same way as positive numbers. The second section can also be omitted if you want negatives formatted the same as positives, but want a different format for zero.
Reference: MSDN Custom Numeric Format Strings: The ";" Section Separator
Format a number to display in thousands or millions without dividing
You can use the group separator "," for scaling as described in Custom Numeric Format Strings.
E.g.
double d = 2234567.00;
Console.WriteLine(d.ToString("#,0,")); // 2,235
Console.WriteLine(d.ToString("#,0,.0")); // 2,234.6
Console.WriteLine(d.ToString("#,0,,.0")); //2.2
How to display dot using Custom Numeric Format Strings in C#
You can include a literal .
by enclosing it in single quotes:
.ToString("#.## грн'.'")
What is the percentage format string to always display the sign?
Not quite using P1
, but same result:
0.12345.ToString("+#.#%;-#.#%");
If you prefer at least one leading digit (e.g. "+0.23%" instead of "+.23%"):
0.12345.ToString("+0.#%;-0.#%"));
Same for trailing digits (e.g. "+14.0%" instead of "+14%"):
0.12345.ToString("+0.0%;-0.0%"));
Reference: https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings#the--section-separator
Can I display float as percent value with positive/negative sign just with formatting string?
You can use conditional string formating:
public static void Main()
{
string format = "+#.00 %;-#.00 %;+0.00 %";
Console.WriteLine((-0.12).ToString(format));
Console.WriteLine((0.12).ToString(format));
Console.WriteLine(0.ToString(format));
}
which outputs:
-12.00 %
+12.00 %
+0.00 %
Unfortunately there is no value for PercentPositivePattern that allows to specify a plus sign application wide.
Custom Numeric Format Strings: Dynamic Decimal Point
No, there is not any built-in format string for this. Your current solution is the best way to accomplish this.
MSDN lists both the standard numeric format strings and custom numeric format strings, so you should be able to see for yourself that none directly matches your needs.
Related Topics
Is There an Alternative to String.Replace That Is Case-Insensitive
ASP.NET MVC Get Textbox Input Value
Unitywebrequest Embedding User + Password Data for Http Basic Authentication Not Working on Android
Request Exceeds the Configured Maxquerystringlength When Using [Authorize]
Disable JavaScript Error in Webbrowser Control
How to Load the Rsa Public Key from File in C#
Drag and Drop to Desktop/Explorer
How to Sort a List of Objects by a Specific Field in C#
How to Update a Claim in ASP.NET Identity
Can't Connect to Localhost on SQL Server Express 2012/2016
How to Get the HTML Output of a Usercontrol in .Net (C#)
Read and Write File on Streamingassetspath
How to Convert JavaScript Date Object to Ticks
Closing Excel Application Process in C# After Data Access
Ef Code-First One-To-One Relationship: Multiplicity Is Not Valid in Role * in Relationship
Is There Really Any Way to Uniquely Identify Any Computer at All