Surprising int.ToString output - c#

I have been working on a project, and found an interesting problem:
2.ToString("TE"+"000"); // output = TE000
2.ToString("TR"+"000"); // output = TR002
I also have tried with several strings other than "TE" but all have the same correct output.
Out of curiosity, I am wondering how come this could have happened?

Simply based on Microsoft's documentation, Custom Numeric Format Strings, your strings "TE000" and "TR000" are both custom format strings, but clearly they are parsed differently.
2.ToString("TE000") is just a bug in the formatter; it's going down a buggy path because of the unescaped "E". So it's unexpectedly assuming the whole thing is a literal.
2.ToString("TR000") is being interpreted as an implied "TR" literal plus 3 zero-filled digits for an integer value; therefore, you get "TR002".
If you truly want TE and TR verbatim, the expressions 2.ToString("\"TE\"000") and 2.ToString("\"TR\"000") will accomplish that for you by specifying TE and TR as explicit literals, instead of letting the formatter guess if they are valid format specifiers (and getting it wrong).

The ToString needs to PARSE the format string and understand what to do with it.
Let's take a look to the following examples:
2.ToString("TE000"); //output TE000
2.ToString("E000"); //output 2E+000
2.ToString("0TE000); //output 2TE000
2.ToString("T"); //throws exception
2.ToString("TT"); //output TT
This shows that if the ToString parser can understand at least part of the format, it will assume that the rest is just extra characters to print with it. If the format is invalid for the given number (like when you use a DateTime string format on a number), it will throw an exception. If it can not make sense of the format, it will return the format string itself as the result.

You cannot use a numeric format to achieve a custom format, instead use something like this:
int i = 2;
String.Format("TE{0:X3}", i);

See Custom Numeric Format Strings. The E means the exponent part of the scientific notation of the number. Since 2 is 2E000 in exponential notation, that might explain it.

Related

Prevent C# from using 'E+x' with large numbers [duplicate]

How to convert double to string without the power to 10 representation (E-05)
double value = 0.000099999999833333343;
string text = value.ToString();
Console.WriteLine(text); // 9,99999998333333E-05
I'd like the string text to be 0.000099999999833333343 (or nearly that, I'm not doing rocket science:)
I've tried the following variants
Console.WriteLine(value.ToString()); // 9,99999998333333E-05
Console.WriteLine(value.ToString("R20")); // 9,9999999833333343E-05
Console.WriteLine(value.ToString("N20")); // 0,00009999999983333330
Console.WriteLine(String.Format("{0:F20}", value)); // 0,00009999999983333330
Doing tostring N20 or format F20 seems closest to what I want, but I do end up with a lot of trailing zeros, is there a clever way to avoid this? I'd like to get as close to the double representation as possible 0.000099999999833333343
Use String.Format() with the format specifier. I think you want {0:F20} or so.
string formatted = String.Format("{0:F20}", value);
How about
Convert.ToDecimal(doubleValue).ToString()
You don't need string.Format(). Just put the right format string in the existing .ToString() method. Something like "N" should do.
Use string.Format with an appropriate format specifier.
This blog post has a lot of examples: http://blogs.msdn.com/kathykam/archive/2006/03/29/564426.aspx

Format of a string after change of double to string

I have a double, and I want to change it to a string, like this:
double value;
string myString = value.toString();
When value is a number with less than 4 digits after the point, it works fine.
For example,
if value is 0, myString will be 0.
if value is 0.01, myString will be 0.01.
But in cases when value has 4 or more digits after the point, myString is created with a floating point (for example, 1E-05).
I want myString to be created in a format of 0.0000000X for any number of digits after the point, and never use the 1E-0X method.
I also want to keep myString as short as possible, for exmaple when the value is 0, i want myString to be 0 (and not 0.000000).
How can I do it?
Thanks
I'm not sure there's a standard numeric format string that will do what you want, but you can use a custom one:
double d = 0.0000003;
Console.WriteLine(d.ToString("0.#################"));
I don't believe that will handle values which end up having significant digits beyond what I've specified though. Extending the number of hashes doesn't help with numbers such as 3e-20, for example. Is that a problem for you?
Note that because you're using double rather than decimal, you may get a surprise in some cases after arithmetic... If you're trying to preserve a value where the exact digits are really important, you should probably be using decimal instead.
Use one of the double.ToString overloads that accept a format string as an argument.
Check the information on standard numeric format strings and custom numeric format strings to learn about specifying the desired formatting.
the msdn page for Double.ToString() explains it pretty well.
string myString = value.ToString("R");
would do the job.

Formatting strings into groups of 3 digits by periods

I know I can format strings using the String.Format() method. Is it possible to format like this?
Example:
string: 1568
formatted: 1.568
string: 168794521
formatted: 168.794.521
string: 987
formatted: 987
Sorry that I can't make myself more clear.
You can format a number that way, but not a string. For example, if you have an integer value, you can use:
int value = 168794521;
string formatted = value.ToString("N0");
With the proper culture, this will format as shown.
If you are using a string, you would need to convert it. You could also explicitly provide a culture to guarantee "." as a thousands separator:
int value = Int32.Parse("168794521");
string formatted = value.ToString("N0", new CultureInfo("de-DE"));
string someNumericValue = "168794521";
int number = int.Parse(someNumericValue); // error checking might be appropriate
value.ToString("0,0", CultureInfo.CreateSpecificCulture("el-GR"));
This will put points in for thousand specifiers.
It's possible that if you want this, your culture may already do this.
Yes, you can do that. SteveX has written a great blog post on string formatting. You could also look at this blog post, and the MSDN documentation.
You probably want to look at the bottom of this documentation in the "More Resources" section for more info about different types of standard format strings.
Here is the relavant part from the SteveX blog on formatting numbers:
Currency {0:c}
Decimal (Whole number) {0:d}
Scientific {0:e}
Fixed point {0:f}
General {0:g}
Number with commas for thousands {0:n}

DotNet DateTime.ToString strange results

Why does:
DateTime.Now.ToString("M")
not return the month number? Instead it returns the full month name with the day on it.
Apparently, this is because "M" is also a standard code for the MonthDayPattern. I don't want this...I want to get the month number using "M". Is there a way to turn this off?
According to MSDN, you can use either "%M", "M " or " M" (note: the last two will also include the space in the result) to force M being parsed as the number of month format.
What's happening here is a conflict between standard DateTime format strings and custom format specifiers. The value "M" is ambiguous in that it is both a standard and custom format specifier. The DateTime implementation will choose a standard formatter over a customer formatter in the case of a conflict, hence it is winning here.
The easiest way to remove the ambiguity is to prefix the M with the % char. This char is way of saying the following should be interpreted as a custom formatter
DateTime.Now.ToString("%M");
Why not use
DateTime.Now.Month?
You can also use System.DateTime.Now.Month.ToString(); to accomplish the same thing
You can put an empty string literal in the format to make it a composite format:
DateTime.Now.ToString("''M")
It's worth mentioning that the % prefix is required for any single-character format string when using the DateTime.ToString(string) method, even if that string does not represent one of the built-in format string patterns; I came across this issue when attempting to retrieve the current hour. For example, the code snippet:
DateTime.Now.ToString("h")
will throw a FormatException. Changing the above to:
DateTime.Now.ToString("%h")
gives the current date's hour.
I can only assume the method is looking at the format string's length and deciding whether it represents a built-in or custom format string.

Custom Numeric Format Strings: Dynamic Decimal Point

I am trying to format a double in C# such that it uses the thousand separator, and adds digits upto 4 decimal places.
This is straight forward except that I dont want to have the decimal point if it is an integer. Is there a way to do this using the custom numeric format strings rather than an if statement of tenary operator?
Currently I have:
string output = dbl.ToString(dbl == (int)dbl ? "#,##0" : "#,##0.####");
Thanks
I believe your second format string of "#,##0.##" should be exactly what you want -- the # format character is a placeholder that will NOT display zeros.
If you had "#,###.00" then you would get trailing zeros.
test code:
double d = 45.00;
Console.Writeline(d.ToString("#,##0.##"));
Gives output of "45". Setting d to 45.45 gives output "45.45", which sounds like what you're after.
So you had the answer after all! ;)
Incidentally, there's a handy cheat-sheet for format strings (amongst other handy cheat-sheets) at http://john-sheehan.com/blog/net-cheat-sheets/
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.

Categories

Resources