-4

I am trying to display the original value in C# three part display format. I got unexpected result + 29291221321. I am expecting + 29.12121321. Is this a bug or what am I doing wrong?

double value1 = 29.1221321;
string formattingString = $"+ {value1}; - {value1}; 0";
 // returns "+29.1221321; -29.1221321; 0"
Console.WriteLine(value1.ToString(formattingString));
// returns "+ 29291221321" 

Please refer to why i call ToString at the end. It is something known as three part format to separate outcome quickly based on +, - and 0 value https://diptimayapatra.wordpress.com/2014/01/13/3-part-format-of-numbers-in-c/

Note:
I am not expecting to hardcode by specify x numbers of # after decimal places. Please advise if there is a better method of displaying the original decimal value in three part format

 string formattingString = "+ #.############; - #.############; 0";
eulercode
  • 1,107
  • 4
  • 16
  • 29
  • 4
    You are putting the value itself into the formatting string, instead of placeholders. It's unclear what kind of formatting string you even want. – GSerg Mar 09 '21 at 14:49
  • that is quite strange that the semicolon is doing that: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated – Daniel A. White Mar 09 '21 at 14:49
  • 1
    `formattingString` isn't a format string, it's the *output* of the string interpolation operations performed by `$"+ {value1}; - {value1}; 0";`. The second format string works just fine – Panagiotis Kanavos Mar 09 '21 at 14:54
  • 4
    Presumably you want to output formattingString directly `Console.WriteLine(formattingString);` – Ralf Mar 09 '21 at 14:54
  • @GSerg i see 2 upvote on your answer but i don't get what you means. Yes i put the value into the formatting string but by the time string formattingString outcome is `+ 29.1221321; - 29.1221321; 0` which is correct at this time. But then when it move to value1.ToString(formattingString) returns `+29291221321`. Why is this so ? – eulercode Mar 09 '21 at 14:56
  • If you have the value `29.1221321` (code), how should that ever become `+ 29.12121321` in the output? These are different numbers. .122 -> .121 – Thomas Weller Mar 09 '21 at 14:56
  • why do you even use the `.ToString(format)` ? I can't see the goal here. – Franck Mar 09 '21 at 14:57
  • 1
    @eulercode Your question does not make sense. You have achieved the result that you believe is correct (`+ 29.1221321; - 29.1221321; 0`), why are you trying to further pass that result to `ToString()` if it's already correct? It is not a [formatting string](https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings) in the first place. – GSerg Mar 09 '21 at 14:58
  • @GSerg this is C# three part format that i learn to pass +, - and 0 value https://diptimayapatra.wordpress.com/2014/01/13/3-part-format-of-numbers-in-c/ – eulercode Mar 09 '21 at 15:00
  • @Franck this is C# three part format that i learn from a tutorial. The intend is to quickly separate postive, negative and zero. https://stackoverflow.com/questions/66549066/c-sharp-three-part-format-display-original-value – eulercode Mar 09 '21 at 15:01
  • @eulercode You are not doing what you think you are doing. You are supposed to provide a formatting string. You are instead providing a formatted string. It is not clear what you are trying to achieve. You have not explained why `"+ #.############; - #.############; 0"` does not work for you (because that *is* a formatting string). – GSerg Mar 09 '21 at 15:02
  • @GSerg "+ #.############; - #.############; 0" works for me but i do not want it do it that way .... – eulercode Mar 09 '21 at 15:04
  • But `$"+ {value1}; - {value1}; 0";` is not a formatting string. See the examples here : https://learn.microsoft.com/en-us/dotnet/api/system.double.tostring?view=net-5.0#System_Double_ToString_System_String_ – XouDo Mar 09 '21 at 15:05
  • Updated my answer with the understanding that you're wanting something like `#.N` where `N` means unlimited decimal places. I don't think what you're asking is possible with the way interpolation works currently. – Hazel へいぜる Mar 09 '21 at 15:13
  • @eulercode *Why* don't you want to do it in that way? What is the property of that formatting string that does not work for you? – GSerg Mar 09 '21 at 15:14
  • Does this answer your question? [Formatting numbers with significant figures in C#](https://stackoverflow.com/questions/158172/formatting-numbers-with-significant-figures-in-c-sharp) – GSerg Mar 09 '21 at 15:16
  • @HansKesting That is not true for three part formatting. – GSerg Mar 09 '21 at 15:24

3 Answers3

4

Please advise if there is a better method of displaying the original decimal value in three part format

# is already the best way to express what you want, since it will omit non-significant zeros at the end. A double has about 15 to 17 significant digits, so you can put 17 # at the end of your format specifier to get the original value.

double value1 = 1.23456;
string formattingString = "+ #.#################; - #.#################; 0";
Console.WriteLine(value1.ToString(formattingString));
Console.WriteLine((-value1).ToString(formattingString));
Console.WriteLine(0.ToString(formattingString));

Output (note the leading spaces, because you have spaces in your format specifier):

+ 1,23456
 - 1,23456
 0

Check that for a double value with more digits

double value1 = 1.2345678901234567890123;   // too many digits for a double

and compare it to the output of

Console.WriteLine(value1);
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
  • Hi, I accept your answer on this. But i have create a new post that requires further explanation here: https://stackoverflow.com/questions/66549716/c-sharp-three-part-format-output-issue. Hope u can comment there as well why putting `.` inside will cause unpredictable output – eulercode Mar 09 '21 at 15:23
0

You're putting the value into the format specifier instead of your specifier:

string formattingString = $"+ {value1}; - {value1}; 0";

Your snippet should instead look like this:

double value1 = 29.1221321;
string formattingString = $"+ #.############; - #.############; 0";
Console.WriteLine(value1.ToString(formattingString));

With the added understanding that you do not want to use the hard coded number of decimal places (which is understandable given the precision available with double), I'm not aware of a way using interpolation. I'd recommend a simple extension method for it:

public static string ToSignedString(this double value) {
    if (value < 0)
        return $"-{value}";
    else if (value > 0)
        return $"+{value}";
    
    return "0";
}

I don't typically recommend extension methods, but I believe your reasoning for not wanting hard coded decimal places is perhaps the need for the code to be concise due to heavy use.

double value = 29.1221321;
Console.WriteLine(value.ToSignedString());

Not the most graceful solution, but it would work.

Hazel へいぜる
  • 2,751
  • 1
  • 12
  • 44
  • Hi i have mentioned i do not want to use second solution given with hardcoded "#" after decimal places – eulercode Mar 09 '21 at 14:55
  • 1
    @eulercode Depending on what are you intending to calculate the required number of `#`? – GSerg Mar 09 '21 at 14:56
-1

You try to reformat Value1 another time in the Console.WriteLine Change it to :

Console.WriteLine(formattingString);