Jump to content

double.ToString() returns 1E-05 instead of 0.00001

- - - - -

  • Please log in to reply
11 replies to this topic

#1
anotheruser

anotheruser

    Learning Programmer

  • Members
  • PipPipPip
  • 44 posts
Title says it all. How do I force the program to always give out the number without scientific notation? I need the resulting string to be read by a method I wrote that doesn't understand scientific notation later.

#2
TkTech

TkTech

    The Crazy One

  • Moderators
  • 1,396 posts
You need to supply a format string. See Double.ToString Method (String) (System) for explanation and an example.

#3
Syne

Syne

    Newbie

  • Members
  • Pip
  • 4 posts
Like this.

Edit: Ninja'd.

#4
anotheruser

anotheruser

    Learning Programmer

  • Members
  • PipPipPip
  • 44 posts
Thanks, I hadn't noticed I could use a string as a parameter. I only noticed I could use IFormatProvider, which seemed like a lot of reading was required to understand it.

#5
anotheruser

anotheruser

    Learning Programmer

  • Members
  • PipPipPip
  • 44 posts
After testing it, turns out the probem isn't solved, yet. I can't find any format that does what I want: the shortest, non-scientific notation

#6
zoranh

zoranh

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 207 posts
Try this:

using System;

namespace Test
{

    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("Enter one double per line. End with empty line.");

            string s = Console.ReadLine();
            double d = 0;

            while (double.TryParse(s, out d))
            {
                Console.WriteLine("{0:0.##########}", d);
                s = Console.ReadLine();
            }
            
        }
    }

}
Each zero in format string specifies mandatory digit. Each hash (#) specifies optional digit.

#7
anotheruser

anotheruser

    Learning Programmer

  • Members
  • PipPipPip
  • 44 posts
Thanks, that solved it. Although I still wonder how to get infinite precision with that. Would I have to use infinite hashs? Maybe I should just write my own method instead, just to be sure, and save myself the hassle of looking all of this up.

#8
zoranh

zoranh

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 207 posts
System.Double has 15 significant digits precision (System.Double), so there's no point in using more than 15 hashes. Anyhow, there's no such thing as "infinite precision" in computers.

#9
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200

zoranh said:

Anyhow, there's no such thing as "infinite precision" in computers.
Read: Arbitrary precision.

GMP (GNU Multiple Precision) and BCMath libraries would suffice.
Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.

#10
zoranh

zoranh

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 207 posts
Then it's not double.ToString() problem. Anyway, if you wish to print out a floating point number in arbitrary precision, you can write your own function that does it. It would go like this:

Input:
x - value to be printed
p - precision (p < 1) such that printing of further decimals stops when printed number differs from x by value smaller than p.

Algorithm:
1. Print part on the left from decimal separator and subtract that from the number - this will keep number in range 0 <= x < 1, and that will be held so until the end of the operation.
2. If x >= p then print decimal separator and proceed to 3; otherwise finished.
3. repeat until x < p or p >= 1 (first case means that all digits that would be printed beyond this point are 0; second case means that we've printed digits up to precision p and we must stop):
3a. x = x * 10 - this would bubble up the next digit
3b. print trunc(x), which is single digit (possibly 0)
3c. x = x - trun(x) - that would return number into range 0 <= x < 1
3d. p = p * 10 - floating point has been moved to the right by one place by having both x and p multiplied by 10.

Maybe this looks a bit like a mess, but it's got the point.

#11
anotheruser

anotheruser

    Learning Programmer

  • Members
  • PipPipPip
  • 44 posts
I already wrote a method to translate strings to doubles because it didn't occur to me to check if a method for that existed already. It seems odd that no method exists to turn doubles into strings with arbitrary precision. Isn't something like that needed more often? Anyway, at least I learned a few things to use in the future, like format strings and trunc() (I would have used (x % 1) to achieve the same effect, but a method seems more elegant).

Thanks for the help.

#12
anotheruser

anotheruser

    Learning Programmer

  • Members
  • PipPipPip
  • 44 posts
Now I have tried to write a method to to do this myself:

public static string DoubleToString(double Double)

        {

            string result = (Math.Truncate(Double)).ToString();

            Double = (Double - Math.Truncate(Double)) * 10;

            if (Double != 0)

                result += ".";

            while (Double % 1 != 0)

            {

                result += (Math.Truncate(Double)).ToString();

                Double = (Double - Math.Truncate(Double)) * 10;

            }

            return result;

        }

But there is another Problem:
(x - Math.Truncate(x)) is not accurate.

I would guess it has to do with the program using binary internally so that the error occurs because Truncate in a decimal system can't be accurately translated to a binary system.

Is that assumption correct?

And, more importantly, how can I fix that?




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users