Custom Numeric Format String to Always Display the Sign

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



Leave a reply



Submit