科学的記数法なしの二重から文字列への変換


81

.NET Frameworkで科学的記数法を使用せずにdoubleを浮動小数点文字列表現に変換するにはどうすればよいですか?

「小さい」サンプル(有効な数は、1.5E200またはなどの任意のサイズにすることができます1e-200):

3248971234698200000000000000000000000000000000
0.00000000000000000000000000000000000023897356978234562

標準の数値形式はどれもこのようなものではなく、カスタム形式ですはなくも小数点記号の後に開いた桁数を使用できないようです。

そこに与えられた答え目前の問題を解決しないので、これは10の累乗表現なしでdoubleをstringに変換する方法(E-05)の複製ではありませ。この質問で受け入れられた解決策は、固定小数点(20桁など)を使用することでしたが、これは私が望んでいることではありません。固定幅の最大幅は99文字であるため、固定小数点のフォーマットと冗長0のトリミングでも問題は解決しません。

注:ソリューションは、カスタムの数値形式(文化情報に応じて、他の小数点記号など)を正しく処理する必要があります。

編集:問題は、実際には前述の数字を表示することだけです。浮動小数点数がどのように機能し、どのような数を使用して計算できるかを知っています。


1
この質問に対する解決策は今ありますか?
キラ

@Anand、(文字列操作を経て)過度に「いい」ものでなくても機能する2つの解決策(Paul Sasikと私のもの)があります。
ルセロ2015年

回答:


41

汎用¹ソリューションの場合、339の場所を保持する必要があります。

doubleValue.ToString("0." + new string('#', 339))

ゼロ以外の小数点以下の最大桁数は16です。15は小数点の右側にあります。指数は、これらの15桁を最大324桁右に移動できます。(範囲と精度を参照してください。

それはのために働くdouble.Epsilondouble.MinValuedouble.MaxValue、との間で何か。

すべてのフォーマットと文字列の作業はアンマネージCLRコードによって1回のパスで実行されるため、パフォーマンスは正規表現/文字列操作ソリューションよりもはるかに高くなります。また、コードは正しいことを証明するのがはるかに簡単です。

使いやすさとパフォーマンスをさらに向上させるには、次のようにします。

public static class FormatStrings
{
    public const string DoubleFixedPoint = "0.###################################################################################################################################################################################################################################################################################################################################################";
}

¹更新:これもロスレスソリューションであると誤って言いました。実際にはそうではありません。なぜなら、ToStringを除くすべての形式で通常の表示の丸めが行われるからrです。実例。ありがとう、@ Loathing!固定小数点表記でラウンドトリップする機能が必要な場合(つまり、.ToString("r")今日使用している場合)は、Lothingの回答を参照してください。


素晴らしくてかなり短いですが、極端に大きな値が必要ない場合は、10倍速くすることができます。私の答えを参照してください:stackoverflow.com/a/36204442/143684
ygoe 2016年

ありがとう、完璧に働いた。あなたは素晴らしい人間です。賛成。
スヌープ2016年

1
このソリューションは「ロスレス」ではありません。例:String t1 = (0.0001/7).ToString("0." + new string('#', 339)); // 0.0000142857142857143対:String t2 = (0.0001/7).ToString("r"); // 1.4285714285714287E-05小数点以下の桁数で精度が失われます。
2018

30

私は同様の問題を抱えていました、そしてこれは私のために働きました:

doubleValue.ToString("F99").TrimEnd('0')

F99はやり過ぎかもしれませんが、あなたはその考えを理解します。


1
99は十分ではありません、そしてそれは前とコンマの後ろの両方のために仕事を持っています。
ルセロ2011

2
TrimEnd('0')char配列はであるため、十分ですparams。つまり、にchar渡されたTrimEndはすべて自動的に配列にグループ化されます。
Grault 2015年

汎用ソリューションには99では不十分です。doubleValue.ToString("0." + new string('#', 339))ロスレスです。値を使用してこれらのメソッドを比較しますdouble.Epsilon
jnm2 2015年

20

これは、ソース番号(double)が文字列に変換され、その構成要素に解析される文字列解析ソリューションです。次に、ルールによって完全な長さの数値表現に再構成されます。また、要求に応じてロケールも考慮します。

更新:変換のテストには、標準である1桁の整数のみが含まれますが、アルゴリズムは次のような場合にも機能します:239483.340901e-20

using System;
using System.Text;
using System.Globalization;
using System.Threading;

public class MyClass
{
    public static void Main()
    {
        Console.WriteLine(ToLongString(1.23e-2));            
        Console.WriteLine(ToLongString(1.234e-5));           // 0.00010234
        Console.WriteLine(ToLongString(1.2345E-10));         // 0.00000001002345
        Console.WriteLine(ToLongString(1.23456E-20));        // 0.00000000000000000100023456
        Console.WriteLine(ToLongString(5E-20));
        Console.WriteLine("");
        Console.WriteLine(ToLongString(1.23E+2));            // 123
        Console.WriteLine(ToLongString(1.234e5));            // 1023400
        Console.WriteLine(ToLongString(1.2345E10));          // 1002345000000
        Console.WriteLine(ToLongString(-7.576E-05));         // -0.00007576
        Console.WriteLine(ToLongString(1.23456e20));
        Console.WriteLine(ToLongString(5e+20));
        Console.WriteLine("");
        Console.WriteLine(ToLongString(9.1093822E-31));        // mass of an electron
        Console.WriteLine(ToLongString(5.9736e24));            // mass of the earth 

        Console.ReadLine();
    }

    private static string ToLongString(double input)
    {
        string strOrig = input.ToString();
        string str = strOrig.ToUpper();

        // if string representation was collapsed from scientific notation, just return it:
        if (!str.Contains("E")) return strOrig;

        bool negativeNumber = false;

        if (str[0] == '-')
        {
            str = str.Remove(0, 1);
            negativeNumber = true;
        }

        string sep = Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator;
        char decSeparator = sep.ToCharArray()[0];

        string[] exponentParts = str.Split('E');
        string[] decimalParts = exponentParts[0].Split(decSeparator);

        // fix missing decimal point:
        if (decimalParts.Length==1) decimalParts = new string[]{exponentParts[0],"0"};

        int exponentValue = int.Parse(exponentParts[1]);

        string newNumber = decimalParts[0] + decimalParts[1];

        string result;

        if (exponentValue > 0)
        {
            result = 
                newNumber + 
                GetZeros(exponentValue - decimalParts[1].Length);
        }
        else // negative exponent
        {
            result = 
                "0" + 
                decSeparator + 
                GetZeros(exponentValue + decimalParts[0].Length) + 
                newNumber;

            result = result.TrimEnd('0');
        }

        if (negativeNumber)
            result = "-" + result;

        return result;
    }

    private static string GetZeros(int zeroCount)
    {
        if (zeroCount < 0) 
            zeroCount = Math.Abs(zeroCount);

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < zeroCount; i++) sb.Append("0");    

        return sb.ToString();
    }
}

ええと。正直なところ、私はそれが投票されたことに気づいたので、コードをあまり詳しく調べませんでした。私はちょうど今それを読みました、そしてあなたは正しいです。それらは近いです、私はちょうど私のプロセスで正規表現を使用しないことを選択し、私自身の文字列解析を行いました。このソリューションをテストしましたか?完全なコンソールアプリです。
Paul Sasik 2009年

まだ、すぐにそれを行います...;)
Lucero

3
これは、正規表現を削除する必要がないため、より読みやすくなっています。
グレゴリー

+1 LOL @ "grok theregex"大好きです。私はそれを私の開発の一部にします!ありがとう。
Paul Sasik 2009年

さて、正規表現のものは、少なくともいくつかの配列の不特定のインデックスの代わりにうまく名前が付けられたグループを持っています...;)
Lucero

13

toをキャストしてdoubleからdecimal実行できますToString()

(0.000000005).ToString()   // 5E-09
((decimal)(0.000000005)).ToString()   // 0,000000005

64ビットdoubleから128ビットdecimalまたは300文字を超えるフォーマット文字列にキャストする、より高速なパフォーマンステストは行っていません。ああ、変換中にオーバーフローエラーが発生する可能性がありますが、値が適合する場合、decimalこれは正常に機能するはずです。

更新:キャストははるかに高速のようです。他の回答で与えられているように準備されたフォーマット文字列を使用すると、100万回のフォーマットは2.3秒かかり、キャストはわずか0.19秒です。繰り返し可能。これは10倍高速です。今では、値の範囲についてのみです。


残念ながら、これは非常に大きな数または小さな数の特定の仕様では機能しません。((decimal)(1e-200)).ToString()たとえば、0どちらが間違っているかを返します。
ルセロ2016年

1
公平を期して、アップルとアップルを比較するには、この方法をと比較する必要がありますdouble.ToString("0.############################")。私のテストによると、あなたの方が3倍速いだけです。いずれにせよ、下の数字を印刷する必要1e-28がなく、doubleが大きくないことが確実にわかっている場合にのみ、有効な答えになります。どちらも元の質問の制約ではありません。
jnm2 2016年

2
値の範囲を知っていることを考えると、これはかなり良い解決策です
Artur Udod 2017年

8

これは私がこれまでに得たものであり、機能しているようですが、おそらく誰かがより良い解決策を持っています:

private static readonly Regex rxScientific = new Regex(@"^(?<sign>-?)(?<head>\d+)(\.(?<tail>\d*?)0*)?E(?<exponent>[+\-]\d+)$", RegexOptions.IgnoreCase|RegexOptions.ExplicitCapture|RegexOptions.CultureInvariant);

public static string ToFloatingPointString(double value) {
    return ToFloatingPointString(value, NumberFormatInfo.CurrentInfo);
}

public static string ToFloatingPointString(double value, NumberFormatInfo formatInfo) {
    string result = value.ToString("r", NumberFormatInfo.InvariantInfo);
    Match match = rxScientific.Match(result);
    if (match.Success) {
        Debug.WriteLine("Found scientific format: {0} => [{1}] [{2}] [{3}] [{4}]", result, match.Groups["sign"], match.Groups["head"], match.Groups["tail"], match.Groups["exponent"]);
        int exponent = int.Parse(match.Groups["exponent"].Value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
        StringBuilder builder = new StringBuilder(result.Length+Math.Abs(exponent));
        builder.Append(match.Groups["sign"].Value);
        if (exponent >= 0) {
            builder.Append(match.Groups["head"].Value);
            string tail = match.Groups["tail"].Value;
            if (exponent < tail.Length) {
                builder.Append(tail, 0, exponent);
                builder.Append(formatInfo.NumberDecimalSeparator);
                builder.Append(tail, exponent, tail.Length-exponent);
            } else {
                builder.Append(tail);
                builder.Append('0', exponent-tail.Length);
            }
        } else {
            builder.Append('0');
            builder.Append(formatInfo.NumberDecimalSeparator);
            builder.Append('0', (-exponent)-1);
            builder.Append(match.Groups["head"].Value);
            builder.Append(match.Groups["tail"].Value);
        }
        result = builder.ToString();
    }
    return result;
}

// test code
double x = 1.0;
for (int i = 0; i < 200; i++) {
    x /= 10;
}
Console.WriteLine(x);
Console.WriteLine(ToFloatingPointString(x));

-1は、次の状態の解を提供しないためです(そして、それはできません)。doubled1 = 1e-200; d = d + 1; ToFloatingPointString(d)は、ここで1を返します。1,000ではありません........... 000001。
JCasso 2009年

5
非常に小さなダブルに1を追加することはあなたの考えであり、目前の質問とは何の関係もありません。d = d + 1なしで実行すると、実際には0.000 ..... 0001が表示されることがわかります。
ルセロ

「一定の」値を設定する代わりに、実行時に1e-200を計算する方法を見つけて、投票します。
JCasso 2009年

2
問題ない。double x = 1.0; for (int i = 0; i < 200; i++) x /= 10; Console.WriteLine(x);
ルセロ

6
これは、実際には15桁しか意味がないためですが、指数を使用してそれらを「シフト」して、非常に大きくしたり小さくしたりすることができます。ただし、有効桁数を超え、有効桁数が多いほど小さい部分が失われるため、15桁を超える非常に小さい数値を追加することはできません。したがって、同様の範囲の数値(1e-200と1e-200、または1 + 1、または1e200 + 1e200の加算など)で計算することはできますが、そのような値を混合すると、小さい方の値が四捨五入されます。
ルセロ

4

#.###...###またはを使用する際の問題F99は、小数点以下の桁数の精度が維持されないことです。例:

String t1 = (0.0001/7).ToString("0." + new string('#', 339)); // 0.0000142857142857143
String t2 = (0.0001/7).ToString("r");                         //      1.4285714285714287E-05

の問題DecimalConverter.csはそれが遅いということです。このコードはSasikの答えと同じ考えですが、2倍高速です。下部のユニットテスト方法。

public static class RoundTrip {

    private static String[] zeros = new String[1000];

    static RoundTrip() {
        for (int i = 0; i < zeros.Length; i++) {
            zeros[i] = new String('0', i);
        }
    }

    private static String ToRoundTrip(double value) {
        String str = value.ToString("r");
        int x = str.IndexOf('E');
        if (x < 0) return str;

        int x1 = x + 1;
        String exp = str.Substring(x1, str.Length - x1);
        int e = int.Parse(exp);

        String s = null;
        int numDecimals = 0;
        if (value < 0) {
            int len = x - 3;
            if (e >= 0) {
                if (len > 0) {
                    s = str.Substring(0, 2) + str.Substring(3, len);
                    numDecimals = len;
                }
                else
                    s = str.Substring(0, 2);
            }
            else {
                // remove the leading minus sign
                if (len > 0) {
                    s = str.Substring(1, 1) + str.Substring(3, len);
                    numDecimals = len;
                }
                else
                    s = str.Substring(1, 1);
            }
        }
        else {
            int len = x - 2;
            if (len > 0) {
                s = str[0] + str.Substring(2, len);
                numDecimals = len;
            }
            else
                s = str[0].ToString();
        }

        if (e >= 0) {
            e = e - numDecimals;
            String z = (e < zeros.Length ? zeros[e] : new String('0', e));
            s = s + z;
        }
        else {
            e = (-e - 1);
            String z = (e < zeros.Length ? zeros[e] : new String('0', e));
            if (value < 0)
                s = "-0." + z + s;
            else
                s = "0." + z + s;
        }

        return s;
    }

    private static void RoundTripUnitTest() {
        StringBuilder sb33 = new StringBuilder();
        double[] values = new [] { 123450000000000000.0, 1.0 / 7, 10000000000.0/7, 100000000000000000.0/7, 0.001/7, 0.0001/7, 100000000000000000.0, 0.00000000001,
         1.23e-2, 1.234e-5, 1.2345E-10, 1.23456E-20, 5E-20, 1.23E+2, 1.234e5, 1.2345E10, -7.576E-05, 1.23456e20, 5e+20, 9.1093822E-31, 5.9736e24, double.Epsilon };

        foreach (int sign in new [] { 1, -1 }) {
            foreach (double val in values) {
                double val2 = sign * val;
                String s1 = val2.ToString("r");
                String s2 = ToRoundTrip(val2);

                double val2_ = double.Parse(s2);
                double diff = Math.Abs(val2 - val2_);
                if (diff != 0) {
                    throw new Exception("Value {0} did not pass ToRoundTrip.".Format2(val.ToString("r")));
                }
                sb33.AppendLine(s1);
                sb33.AppendLine(s2);
                sb33.AppendLine();
            }
        }
    }
}

3

必須の対数ベースのソリューション。この解決策は数​​学を行う必要があるため、数値の精度が少し低下する可能性があることに注意してください。十分にテストされていません。

private static string DoubleToLongString(double x)
{
    int shift = (int)Math.Log10(x);
    if (Math.Abs(shift) <= 2)
    {
        return x.ToString();
    }

    if (shift < 0)
    {
        double y = x * Math.Pow(10, -shift);
        return "0.".PadRight(-shift + 2, '0') + y.ToString().Substring(2);
    }
    else
    {
        double y = x * Math.Pow(10, 2 - shift);
        return y + "".PadRight(shift - 2, '0');
    }
}

編集:小数点が数値のゼロ以外の部分と交差する場合、このアルゴリズムは惨めに失敗します。シンプルにやってみて行き過ぎました。


入力をありがとう、私はこのような完全に機能するソリューションを実装し、それを私のものと比較しようとします。
ルセロ

3

独自のフォーマッターを作成する必要があった昔は、仮数と指数を分離して、別々にフォーマットしていました。

Jon Skeetによるこの記事(https://csharpindepth.com/articles/FloatingPoint)で、彼は自分のDoubleConverter.csルーチンへのリンクを提供しています。Skeetは、c#のdoubleから仮数と指数抽出するときにもこれを参照します。


リンクをありがとう、私はすでにJonからのコードを試しました、しかし私の目的のためにそれはちょっと正確すぎます。たとえば、0.1は0.1として表示されません(これは技術的には正しいですが、私が必要とするものではありません)...
Lucero

ええ、でもご覧のとおり、Jonのコードの要点は、数値を正確に表示することであり、これは私の場合には多すぎます。ToString()を実行するときにランタイムによって実行される丸めは私にとっては問題ありません。これが、ここで提案するほとんどのソリューションがさらなる処理のベースとしてToString()を使用する理由でもあります。
ルセロ

こんにちは!ジョンの記事へのハイパーリンクが壊れていることをお知らせするために、私は10年後からここに来ました。
NickVaccaro19年

2

負の指数値に対して機能するように、上記のコードを即興で作成しました。

using System;
using System.Text.RegularExpressions;
using System.IO;
using System.Text;
using System.Threading;

namespace ConvertNumbersInScientificNotationToPlainNumbers
{
    class Program
    {
        private static string ToLongString(double input)
        {
            string str = input.ToString(System.Globalization.CultureInfo.InvariantCulture);

            // if string representation was collapsed from scientific notation, just return it:
            if (!str.Contains("E")) return str;

            var positive = true;
            if (input < 0)
            {
                positive = false;
            }

            string sep = Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator;
            char decSeparator = sep.ToCharArray()[0];

            string[] exponentParts = str.Split('E');
            string[] decimalParts = exponentParts[0].Split(decSeparator);

            // fix missing decimal point:
            if (decimalParts.Length == 1) decimalParts = new string[] { exponentParts[0], "0" };

            int exponentValue = int.Parse(exponentParts[1]);

            string newNumber = decimalParts[0].Replace("-", "").
                Replace("+", "") + decimalParts[1];

            string result;

            if (exponentValue > 0)
            {
                if (positive)
                    result =
                        newNumber +
                        GetZeros(exponentValue - decimalParts[1].Length);
                else

                    result = "-" +
                     newNumber +
                     GetZeros(exponentValue - decimalParts[1].Length);


            }
            else // negative exponent
            {
                if (positive)
                    result =
                        "0" +
                        decSeparator +
                        GetZeros(exponentValue + decimalParts[0].Replace("-", "").
                                   Replace("+", "").Length) + newNumber;
                else
                    result =
                    "-0" +
                    decSeparator +
                    GetZeros(exponentValue + decimalParts[0].Replace("-", "").
                             Replace("+", "").Length) + newNumber;

                result = result.TrimEnd('0');
            }
            float temp = 0.00F;

            if (float.TryParse(result, out temp))
            {
                return result;
            }
            throw new Exception();
        }

        private static string GetZeros(int zeroCount)
        {
            if (zeroCount < 0)
                zeroCount = Math.Abs(zeroCount);

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < zeroCount; i++) sb.Append("0");

            return sb.ToString();
        }

        public static void Main(string[] args)
        {
            //Get Input Directory.
            Console.WriteLine(@"Enter the Input Directory");
            var readLine = Console.ReadLine();
            if (readLine == null)
            {
                Console.WriteLine(@"Enter the input path properly.");
                return;
            }
            var pathToInputDirectory = readLine.Trim();

            //Get Output Directory.
            Console.WriteLine(@"Enter the Output Directory");
            readLine = Console.ReadLine();
            if (readLine == null)
            {
                Console.WriteLine(@"Enter the output path properly.");
                return;
            }
            var pathToOutputDirectory = readLine.Trim();

            //Get Delimiter.
            Console.WriteLine("Enter the delimiter;");
            var columnDelimiter = (char)Console.Read();

            //Loop over all files in the directory.
            foreach (var inputFileName in Directory.GetFiles(pathToInputDirectory))
            {
                var outputFileWithouthNumbersInScientificNotation = string.Empty;
                Console.WriteLine("Started operation on File : " + inputFileName);

                if (File.Exists(inputFileName))
                {
                    // Read the file
                    using (var file = new StreamReader(inputFileName))
                    {
                        string line;
                        while ((line = file.ReadLine()) != null)
                        {
                            String[] columns = line.Split(columnDelimiter);
                            var duplicateLine = string.Empty;
                            int lengthOfColumns = columns.Length;
                            int counter = 1;
                            foreach (var column in columns)
                            {
                                var columnDuplicate = column;
                                try
                                {
                                    if (Regex.IsMatch(columnDuplicate.Trim(),
                                                      @"^[+-]?[0-9]+(\.[0-9]+)?[E]([+-]?[0-9]+)$",
                                                      RegexOptions.IgnoreCase))
                                    {
                                        Console.WriteLine("Regular expression matched for this :" + column);

                                        columnDuplicate = ToLongString(Double.Parse
                                                                           (column,
                                                                            System.Globalization.NumberStyles.Float));

                                        Console.WriteLine("Converted this no in scientific notation " +
                                                          "" + column + "  to this number " +
                                                          columnDuplicate);
                                    }
                                }
                                catch (Exception)
                                {

                                }
                                duplicateLine = duplicateLine + columnDuplicate;

                                if (counter != lengthOfColumns)
                                {
                                    duplicateLine = duplicateLine + columnDelimiter.ToString();
                                }
                                counter++;
                            }
                            duplicateLine = duplicateLine + Environment.NewLine;
                            outputFileWithouthNumbersInScientificNotation = outputFileWithouthNumbersInScientificNotation + duplicateLine;
                        }

                        file.Close();
                    }

                    var outputFilePathWithoutNumbersInScientificNotation
                        = Path.Combine(pathToOutputDirectory, Path.GetFileName(inputFileName));

                    //Create Directory If it does not exist.
                    if (!Directory.Exists(pathToOutputDirectory))
                        Directory.CreateDirectory(pathToOutputDirectory);

                    using (var outputFile =
                        new StreamWriter(outputFilePathWithoutNumbersInScientificNotation))
                    {
                        outputFile.Write(outputFileWithouthNumbersInScientificNotation);
                        outputFile.Close();
                    }

                    Console.WriteLine("The transformed file is here :" +
                        outputFilePathWithoutNumbersInScientificNotation);
                }
            }
        }
    }
}

このコードは入力ディレクトリを取り、区切り文字に基づいて科学的記数法のすべての値を数値形式に変換します。

ありがとう


1

これを試してください:

public static string DoubleToFullString(double value, 
                                        NumberFormatInfo formatInfo)
{
    string[] valueExpSplit;
    string result, decimalSeparator;
    int indexOfDecimalSeparator, exp;

    valueExpSplit = value.ToString("r", formatInfo)
                         .ToUpper()
                         .Split(new char[] { 'E' });

    if (valueExpSplit.Length > 1)
    {
        result = valueExpSplit[0];
        exp = int.Parse(valueExpSplit[1]);
        decimalSeparator = formatInfo.NumberDecimalSeparator;

        if ((indexOfDecimalSeparator 
             = valueExpSplit[0].IndexOf(decimalSeparator)) > -1)
        {
            exp -= (result.Length - indexOfDecimalSeparator - 1);
            result = result.Replace(decimalSeparator, "");
        }

        if (exp >= 0) result += new string('0', Math.Abs(exp));
        else
        {
            exp = Math.Abs(exp);
            if (exp >= result.Length)
            {
                result = "0." + new string('0', exp - result.Length) 
                             + result;
            }
            else
            {
                result = result.Insert(result.Length - exp, decimalSeparator);
            }
        }
    }
    else result = valueExpSplit[0];

    return result;
}

0

世界中で何百万人ものプログラマーがいるので、誰かがすでにあなたの問題にぶつかった場合は、検索を試みることは常に良い習慣です。解決策がゴミである場合もあります。つまり、独自の解決策を作成するときです。また、次のようなすばらしい解決策がある場合もあります。

http://www.yoda.arachsys.com/csharp/DoubleConverter.cs

(詳細:http//www.yoda.arachsys.com/csharp/floatingpoint.html


1
これは、ebpowerによってすでに投稿されているものと同じです。コメントを参照してください...;)
Lucero

0
string strdScaleFactor = dScaleFactor.ToString(); // where dScaleFactor = 3.531467E-05

decimal decimalScaleFactor = Decimal.Parse(strdScaleFactor, System.Globalization.NumberStyles.Float);

このコードの機能と、他の15ほどの回答との違いについて簡単に説明してください。
JJJ 2017年

Stack Overflowへようこそ!このコードスニペットは質問を解決する可能性がありますが、説明を含めると、投稿の品質を向上させるのに役立ちます。あなたは将来読者のために質問に答えていることを忘れないでください、そしてそれらの人々はあなたのコード提案の理由を知らないかもしれません。また、説明コメントでコードを混雑させないようにしてください。これにより、コードと説明の両方が読みにくくなります。
kayess 2017年

-1

私は間違っているかもしれませんが、それはこのようではありませんか?

data.ToString("n");

http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx


あなたの答えを見て、私はあなたの質問を誤解したに違いありません、ごめんなさい。
csharptest.net 2009年

いいえ、最初は千の区切り記号は必要ありません。次に、コンマの後には常に固定桁数があるようです。N形式のMSDNヘルプも参照してください
Lucero

小数点以下に追加することもできます(つまり、「n8」、「n50」など)。
BrainSlugs83 2013

-1

jcassoが言ったことに基づいて、指数を変更してdouble値を調整し、お気に入りの形式でそれを実行し、形式を適用してから、結果にゼロを埋めて調整を補正します。


IEEE浮動小数点数の指数は2ベースですが、10進数は10ベースです。したがって、これは機能しません。これは、0.1を正確な値としてdoubleに格納できない理由でもあります。または、私があなたの答えを誤解したと思われる場合は、サンプル(コード)を提供してください。
ルセロ

-1

IFormatを使用するだけでよいと思います

ToString(doubleVar, System.Globalization.NumberStyles.Number)

例:

double d = double.MaxValue;
string s = d.ToString(d, System.Globalization.NumberStyles.Number);

6
それもコンパイルされません、コンパイルするものを投稿できますか?
ルセロ2010年

-1

私の解決策は、カスタムフォーマットを使用することでした。これを試して:

double d;
d = 1234.12341234;
d.ToString("#########0.#########");

2
上で示したテスト番号を試してください:d = 1.5E200およびd = 1E-200。結果の文字列には約2000文字が含まれているはずです。そうでない場合、ソリューションは機能しません。
ルセロ2012

汎用ソリューションでは、小数点以下9桁では不十分です。doubleValue.ToString("0." + new string('#', 339))ロスレスです。値を使用してこれらのメソッドを比較しますdouble.Epsilon
jnm2 2015年

-1

これは私にとってはうまくいきます...

double number = 1.5E+200;
string s = number.ToString("#");

//Output: "150000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"

1
はい、それは大きな数に対しては機能しますが、コンマの後ろの何か、特に1.5e-200。のようなものに対しては機能しません。
ルセロ2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.