24

I just came across the wonderful "feature" that .NET will by default do Double.ToString() using scientific notation if there are enough decimal places.

.005.ToString() // ".005"
.00005.ToString() // "5E-05" 

Does anyone know an efficient way to get this to appear as a string in standard (non-scientific) notation?

I've seen this question, but the top two answers seem kind of hacky to me as they both do Double.ToString() and then just reformat the results.

Thanks for any help.

EDIT:

The desired output:

.00005.ToString() == ".00005"

EDIT2:

What is with all the duplicate and close votes? I specifically say in the question that the similar question does not have a satisfactory answer. People on this website get way too power happy.

MY SOLUTION:

In case it's useful to anyone:

/// <summary>
/// Converts the double to a standard notation string.
/// </summary>
/// <param name="d">The double to convert.</param>
/// <returns>The double as a standard notation string.</returns>
public static String ToStandardNotationString(this double d)
{
    //Keeps precision of double up to is maximum
    return d.ToString(".#####################################################################################################################################################################################################################################################################################################################################");

}

NOTE: This only works for values > 1. I haven't found an efficient way to do this for all values yet.

Community
  • 1
  • 1
MgSam
  • 12,139
  • 19
  • 64
  • 95
  • You realize that, down at the metal of the computer, floating-point numbers are stored in what amounts to base-2 scientific notation. This isn't a sarcastic "feature"; the behavior is integral to the type. While it's possible to display floats in purely decimal format (I support Tim S's answer on this), a number like 2.68E201 will simply have a *lot* of zeroes. – KeithS Feb 19 '13 at 18:36
  • 2
    @KeithS ToString() should have a consistent behavior, regardless of the hardware. That's the whole point of abstractions upon which all modern programming is based. One would expect that to get something in scientific notation, one would specify that. – MgSam Feb 19 '13 at 18:43
  • I can't answer anymore, but you could cast the `double` to `decimal` and then do `ToString()`. I haven't done performance testing which is faster, `decimal` or a format string of over 300 chars. – ygoe Mar 24 '16 at 15:46

1 Answers1

17

See the Standard and Custom Numeric Format Strings. I think you're looking for ".################":

.00005.ToString(".################") // returns ".00005"

It's somewhat hackish, yes, but it works, as long as you don't have more than that many places after the decimal. If you do, you might want to use a StringBuilder to build out about 330 #s in your string (double.Epsilon is on the order of E-324).

Tim S.
  • 55,448
  • 7
  • 96
  • 122
  • I was afraid this might be the only reasonable way. It's more efficient to make the 324 length ".###" string a constant though, rather than compute it at runtime. – MgSam Feb 19 '13 at 18:41
  • 1
    @MgSam More efficent, sure...but if you're only computing it once and saving it, the efficency is negligible. And the clarity gained from generating the string via a loop might be worth it...you could see exactly how long the string was, and have a comment as to why...and easily adjust it if you ever change from a double to a float or whatever, etc. This is probably getting a bit overly nitpicky, however. – Beska Feb 19 '13 at 18:46
  • 2
    @Beska Using a loop would be pointless when you can do `var format = "." + new string('#', 324)` – Lukazoid Feb 19 '13 at 19:28
  • @Lukazoid Whatever. Sure. My point (that I probably didn't make clearly) was that hardcoding a long string to a constant wasn't going to save much time over generating it once when the program runs...and seeing a "324" in the generation process, such as from a loop or like in your example, is better because will make it obvious that the string is exactly 324 characters long (something that wouldn't be obvious from a long constant.) I was just advocating NOT doing what he ended up doing, because the next programmer looking at that huge string has no idea how many hashes there are, or why. – Beska Feb 19 '13 at 20:27
  • 1
    @Beska Thus a comment. The whole argument of "don't hard code it" is kind of silly, IMO. Should Math.Pi should calculate Pi each time rather than hardcoding it? This is the whole point of constants+documentation. – MgSam Feb 19 '13 at 20:39
  • I was just commenting on the notion of it being more efficent. Sure...but (probably) negligible. Also, I don't think it's quite the same thing as Math.Pi...Pi is hard to compute, this is easy...Math.Pi never changes, this, being used internally, might. But your point about good documentation eliminating most of these concerns is probably the key one. If it's well documented/commented, none of these things are really going to matter much, and the next programmer will be happy with whatever. But the comment in there now doesn't explain how many hashes are there or why. Again, just nitpicking. – Beska Feb 20 '13 at 01:23
  • (And yes, I understand double isn't going to change, but since you're writing this now, it stands to reason someone may want to change/optimize/extend it later) – Beska Feb 20 '13 at 01:27