ฉันจะแยกสตริงที่มีจุดทศนิยมให้เป็นสองเท่าได้อย่างไร


231

ฉันต้องการที่จะแยกสตริงเหมือน"3.5"คู่ อย่างไรก็ตาม

double.Parse("3.5") 

ให้ผลตอบแทน 35 และ

double.Parse("3.5", System.Globalization.NumberStyles.AllowDecimalPoint) 

FormatExceptionพ่น

ตอนนี้ตำแหน่งที่ตั้งของคอมพิวเตอร์ของฉันถูกตั้งค่าเป็นภาษาเยอรมันโดยที่ใช้เครื่องหมายจุลภาคเป็นตัวคั่นทศนิยม อาจต้องทำอะไรกับมันและdouble.Parse()คาดหวังว่าจะ"3,5"เป็นอินพุท แต่ฉันไม่แน่ใจ

ฉันจะแยกสตริงที่มีตัวเลขทศนิยมที่อาจหรือไม่สามารถจัดรูปแบบตามที่ระบุในสถานที่ปัจจุบันของฉันได้อย่างไร


เครื่องหมายจุลภาคทศนิยมจะมีผลต่อการส่งออกอย่างแน่นอน
ChrisF

12
อย่าลืมวิธี double.TryParse () หากเหมาะสมกับสถานการณ์ของคุณ
Kyle Gagnet

คำตอบ:


414
double.Parse("3.5", CultureInfo.InvariantCulture)

ฉันชอบที่จะใช้XmlConvertคลาส ... คุณมีความคิดใด ๆ ว่าดีกว่าแย่กว่าและ / หรือแตกต่างจากการใช้CultureInfo.InvariantCultureหรือไม่?
ChrisW

1
ดีXmlConvertไม่ได้ตั้งใจจริงๆที่จะนำมาใช้เพื่อแยกค่า double เดียวในรหัส ฉันชอบที่จะใช้double.ParseหรือConvert.ToDoubleทำให้ความตั้งใจของฉันชัดเจน
Mehrdad Afshari

4
ซึ่งหมายความว่า doulble.Parse ใช้วัฒนธรรมเริ่มต้นซึ่งอาจไม่มีจุดเป็นทศนิยม?
Ahmed Said

3
หากแปลง 12345678.12345678 จะแปลงเกินไป 12345678.123457
PUG

4
ไม่ทำงานสำหรับฉัน: ข้ามเครื่องหมายจุลภาคและผลตอบแทนและ int เป็นสองเท่า
fnc12

75

ฉันมักจะใช้ฟังก์ชั่นหลายวัฒนธรรมในการแยกวิเคราะห์อินพุตของผู้ใช้ส่วนใหญ่เพราะถ้ามีคนคุ้นเคยกับ numpad และใช้วัฒนธรรมที่ใช้เครื่องหมายจุลภาคเป็นตัวคั่นทศนิยมบุคคลนั้นจะใช้จุดของ numpad แทนเครื่องหมายจุลภาค

public static double GetDouble(string value, double defaultValue)
{
    double result;

    //Try parsing in the current culture
    if (!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.CurrentCulture, out result) &&
        //Then try in US english
        !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) &&
        //Then in neutral language
        !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result))
    {
        result = defaultValue;
    }

    return result;
}

แต่ระวังไว้ว่าความเห็นของนิกกี้เป็นเรื่องจริง เพื่อป้องกันของฉันฉันใช้ฟังก์ชั่นนี้ในสภาพแวดล้อมที่มีการควบคุมที่ฉันรู้ว่าวัฒนธรรมสามารถเป็น en-US, en-CA หรือ fr-CA ฉันใช้ฟังก์ชั่นนี้เพราะในภาษาฝรั่งเศสเราใช้เครื่องหมายจุลภาคเป็นตัวคั่นทศนิยม แต่ใครก็ตามที่เคยทำงานด้านการเงินมักจะใช้ตัวคั่นทศนิยมบน numpad แต่นี่คือจุดไม่ใช่เครื่องหมายจุลภาค ดังนั้นแม้ในวัฒนธรรม fr-CA ฉันต้องแยกวิเคราะห์ตัวเลขที่จะมีจุดเป็นตัวคั่นทศนิยม


18
ฉันไม่แน่ใจว่าเป็นความคิดที่ดี คุณไม่สามารถแยกวิเคราะห์คู่ได้อย่างน่าเชื่อถือหากคุณไม่รู้จักวัฒนธรรม: ในเยอรมนีค่าสองเท่าอาจมี '.'s แต่พวกเขาคิดว่าเป็นตัวคั่นหลักพัน ดังนั้นในกรณีของ Legate GetDouble ("3.5") จะส่งคืน 35 ในภาษาเยอรมันและ 3.5 ในสภาพแวดล้อมที่ใช้งานเรา
Niki

ไม่ปิแอร์อแลงถูกต้องตามที่เขียนไว้ หากวัฒนธรรมของคุณบอกว่า "dot is a separator" ดังนั้น "3.5" จึงถูกมองว่าเป็น "35" และมันก็ดี อย่างไรก็ตามหากคุณไม่มีกฎสำหรับ "จุด" ดังนั้นตัวอักษรจะถูกแยกเป็นทศนิยมและมันก็ใช้ได้เช่นกัน ฉันจะหลีกเลี่ยงการลองใช้วัฒนธรรม enUS แต่มันเป็นทางเลือกส่วนตัว
xryl669

หากคุณใช้ numpad in culture ร่วมกับเครื่องหมายจุลภาคคีย์จุดจะถูกตั้งค่าเครื่องหมายจุลภาค
CrazyBaran

ตัวแยกเลขฐานสิบ numpad ขึ้นอยู่กับรูปแบบแป้นพิมพ์ (และไม่ใช่การตั้งค่าภูมิภาค - อย่างน้อยใน Windows 7) (ฉันใช้ภาษาฮังการีเพื่อเขียนข้อความอีเมล ... และ en-US เพื่อเขียนรหัสเพื่อให้สามารถเป็นจุดได้ หรือเครื่องหมายจุลภาคนอกจากนี้ฉันยังใช้การตั้งค่าภูมิภาคแบบกำหนดเองซึ่งฉันเปลี่ยนตัวแยกทศนิยมจาก ',' เป็น '.' และตัวคั่นรายการจาก ';' เป็น ',' คุณรู้สาเหตุ csv ... โชคดีที่เราทุกคนเขียน แอปวัฒนธรรม;)
Steven Spark

25

ฉันไม่สามารถเขียนความคิดเห็นดังนั้นฉันเขียนที่นี่:

double.Parse ("3.5", CultureInfo.InvariantCulture)ไม่ใช่ความคิดที่ดีเพราะในแคนาดาเราเขียน 3,5 แทนที่จะเป็น 3.5 และฟังก์ชั่นนี้ให้ผลเป็นค่า 35

ฉันทดสอบทั้งสองอย่างในคอมพิวเตอร์ของฉัน:

double.Parse("3.5", CultureInfo.InvariantCulture) --> 3.5 OK
double.Parse("3,5", CultureInfo.InvariantCulture) --> 35 not OK

นี่เป็นวิธีที่ถูกต้องที่Pierre-Alain Vigeantกล่าวถึง

public static double GetDouble(string value, double defaultValue)
{
    double result;

    // Try parsing in the current culture
    if (!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.CurrentCulture, out result) &&
        // Then try in US english
        !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) &&
        // Then in neutral language
        !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result))
    {
        result = defaultValue;
    }
    return result;
}

1
Re: "... เพราะในแคนาดาเราเขียน 3,5 แทนที่จะเป็น 3.5"คุณแน่ใจหรือไม่? ตามเครื่องหมายทศนิยม :. "ประเทศที่มีการจุด" "ใช้เป็นเครื่องหมายทศนิยม ได้แก่ ... แคนาดา (เมื่อใช้ภาษาอังกฤษ)" มันเกี่ยวกับการใช้ Windows รุ่นภาษาฝรั่งเศสใช่ไหม
Peter Mortensen

Baybe เพราะรุ่นภาษาฝรั่งเศส ในมอนทรีอัลเราเขียน 3,5 ไม่ใช่ 3.5
Malus Jan

ดังนั้นตามตรรกะของคุณพวกเขาเพียง 1 คนเท่านั้นที่ผลตอบแทนจริง?
batmaci


ยังคงมีข้อผิดพลาด สำหรับสตริงอินพุตเช่น GetDouble ("10 ,,,,,,,,, 0", 0.0) ฟังก์ชันที่กล่าวถึงจะส่งคืน 100
Krivers

21
Double.Parse("3,5".Replace(',', '.'), CultureInfo.InvariantCulture)

แทนที่เครื่องหมายจุลภาคด้วยจุดก่อนที่จะแยก มีประโยชน์ในประเทศที่มีเครื่องหมายจุลภาคเป็นตัวคั่นทศนิยม คิดเกี่ยวกับการ จำกัด การป้อนข้อมูลผู้ใช้ (ถ้าจำเป็น) ไปยังเครื่องหมายจุลภาคหรือจุดเดียว


1
คำตอบที่ถูกต้องมากยิ่งขึ้นกว่าคำตอบที่ได้ +133 คะแนน ... ช่วยให้สามารถใช้ชีวิตทั้งสองระบบด้วย "," หรือ " ตัวคั่นทศนิยม ...
Badiboy

@Badiboy คุณสามารถอธิบายสิ่งที่ผิดกับคำตอบนี้ได้อย่างไร ตามที่ฉันเข้าใจ InvariantCulture มักจะมี '.' เป็นตัวแยกทศนิยม ดังนั้นควรทำงานกับทั้งสองระบบ
Alex P.

@ Alex11223 คุณพูดถูก นั่นเป็นเหตุผลที่ฉันพูดว่าคำตอบนี้ดีกว่าคำตอบที่ได้รับความนิยมมากกว่า PS: การพูดอย่างเป็นมิตรกับรหัสนี้จะล้มเหลวหากคุณมี "," เป็น LIST SEPARATOR (เช่น 1,234,560.01) แต่ฉันไม่รู้วิธีแก้ปัญหานี้เลย :)
Badiboy

4
นี่ไม่ใช่คำตอบที่ดีเพราะในบางวัฒนธรรมมีตัวคั่นหลักพันและสามารถใช้ได้ หากคุณเปลี่ยนเป็นจุดคุณจะพบว่ามีหลายจุดและการแยกวิเคราะห์จะล้มเหลว: Double.Parse ((12345.67) .ToString ("N", ใหม่ CultureInfo ("en")) แทนที่ (',', ' '), CultureInfo.InvariantCulture) เพราะ (12345.67) .ToString ("N", ใหม่ CultureInfo ("en")). แทนที่ (', ','. ') จะถูกจัดรูปแบบเป็น "12.345.67"
codingdave

1,234.56 -> 1.234.56 ไม่ใช่ตัวแยกวิเคราะห์ แนวคิดอื่นคือการตรวจสอบว่าหมายเลขมี '.' หรือไม่ และ ',' และแทนที่ ',' ด้วยสตริงว่างและถ้ามีเพียง ',' เครื่องหมายจุลภาคที่แสดงแทนที่มันเป็น '.'
GDocal

16

เคล็ดลับคือการใช้วัฒนธรรมคงที่เพื่อแยกจุดในทุกวัฒนธรรม

double.Parse("3.5", System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.NumberFormatInfo.InvariantInfo);

11

ดูทุกคำตอบข้างต้นที่เสนอให้เขียนการแทนที่สตริงด้วยสตริงคงที่อาจผิดเท่านั้น ทำไม? เพราะคุณไม่เคารพการตั้งค่าภูมิภาคของ Windows! Windows ช่วยให้ผู้ใช้มีอิสระในการตั้งค่าตัวคั่นที่ต้องการ S / เขาสามารถเปิดแผงควบคุมเข้าสู่แผงภูมิภาคคลิกที่ขั้นสูงและเปลี่ยนตัวละครได้ตลอดเวลา แม้ในระหว่างที่โปรแกรมของคุณทำงาน คิดอย่างนี้ ทางออกที่ดีจะต้องตระหนักถึงเรื่องนี้

ดังนั้นก่อนอื่นคุณจะต้องถามตัวเองว่าหมายเลขนี้มาจากไหนที่คุณต้องการแยกวิเคราะห์ ถ้ามันมาจากอินพุตใน. NET Framework ไม่มีปัญหาเพราะมันจะอยู่ในรูปแบบเดียวกัน แต่บางทีมันมาจากข้างนอกอาจมาจากเซิร์ฟเวอร์ภายนอกอาจมาจากฐานข้อมูลเก่าที่รองรับคุณสมบัติสตริงเท่านั้น ที่นั่นผู้ดูแลระบบ db ควรกำหนดกฎในการจัดรูปแบบตัวเลขที่จะจัดเก็บ หากคุณรู้เช่นนั้นจะเป็น US DB ที่มีรูปแบบ US คุณสามารถใช้รหัสนี้ได้:

CultureInfo usCulture = new CultureInfo("en-US");
NumberFormatInfo dbNumberFormat = usCulture.NumberFormat;
decimal number = decimal.Parse(db.numberString, dbNumberFormat);

สิ่งนี้จะทำงานได้ดีทุกที่ในโลก และโปรดอย่าใช้ 'Convert.ToXxxx' คลาส 'แปลง' เป็นความคิดพื้นฐานสำหรับการแปลงในทิศทางใด ๆ นอกจากนี้: คุณสามารถใช้กลไกที่คล้ายกันสำหรับ DateTimes ด้วย


ตกลงกัน! การพยายามใช้คุณลักษณะทางวัฒนธรรมด้วยตนเองในที่สุดก็จะส่งผลให้ในกรณีที่คุณไม่คาดคิดและปวดหัวขนาดใหญ่ ให้. NET จัดการกับมันอย่างถูกต้อง
Khalos

2
ปัญหาใหญ่คือเมื่อผู้ใช้กำลังใช้ตัวคั่นทศนิยมที่ไม่ถือเป็นตัวแยกทศนิยมสำหรับการตั้งค่าทางวัฒนธรรม
EdmundYeung99

3
string testString1 = "2,457";
string testString2 = "2.457";    
double testNum = 0.5;
char decimalSepparator;
decimalSepparator = testNum.ToString()[1];

Console.WriteLine(double.Parse(testString1.Replace('.', decimalSepparator).Replace(',', decimalSepparator)));
Console.WriteLine(double.Parse(testString2.Replace('.', decimalSepparator).Replace(',', decimalSepparator)));

2

สองเซ็นต์ของฉันในหัวข้อนี้พยายามเสนอวิธีการแปลงทั่วไปแบบสองเท่า:

private static double ParseDouble(object value)
{
    double result;

    string doubleAsString = value.ToString();
    IEnumerable<char> doubleAsCharList = doubleAsString.ToList();

    if (doubleAsCharList.Where(ch => ch == '.' || ch == ',').Count() <= 1)
    {
        double.TryParse(doubleAsString.Replace(',', '.'),
            System.Globalization.NumberStyles.Any,
            CultureInfo.InvariantCulture,
            out result);
    }
    else
    {
        if (doubleAsCharList.Where(ch => ch == '.').Count() <= 1
            && doubleAsCharList.Where(ch => ch == ',').Count() > 1)
        {
            double.TryParse(doubleAsString.Replace(",", string.Empty),
                System.Globalization.NumberStyles.Any,
                CultureInfo.InvariantCulture,
                out result);
        }
        else if (doubleAsCharList.Where(ch => ch == ',').Count() <= 1
            && doubleAsCharList.Where(ch => ch == '.').Count() > 1)
        {
            double.TryParse(doubleAsString.Replace(".", string.Empty).Replace(',', '.'),
                System.Globalization.NumberStyles.Any,
                CultureInfo.InvariantCulture,
                out result);
        }
        else
        {
            throw new ParsingException($"Error parsing {doubleAsString} as double, try removing thousand separators (if any)");
        }
    }

    return result;
}

ทำงานตามที่คาดไว้ด้วย:

  • 1.1
  • 1,1
  • 1,000,000,000
  • 1.000.000.000
  • 1,000,000,000.99
  • 1.000.000.000,99
  • 5,000,111.3
  • 5.000.111,3
  • 0.99,000,111,88
  • 0,99.000.111.88

ไม่มีการแปลงค่าเริ่มต้นจะดำเนินการดังนั้นมันจะล้มเหลวในการพยายามที่จะแยก1.3,14, 1,3.14หรือกรณีที่คล้ายกัน


1
"1,000" ตั้งใจเป็นหนึ่งพันจะล้มเหลว
Defkon1

1

รหัสต่อไปนี้ทำงานในสถานการณ์ใด ๆ มันเป็นการแยกวิเคราะห์เล็กน้อย

List<string> inputs = new List<string>()
{
    "1.234.567,89",
    "1 234 567,89",
    "1 234 567.89",
    "1,234,567.89",
    "123456789",
    "1234567,89",
    "1234567.89",
};
string output;

foreach (string input in inputs)
{
    // Unify string (no spaces, only .)
    output = input.Trim().Replace(" ", "").Replace(",", ".");

    // Split it on points
    string[] split = output.Split('.');

    if (split.Count() > 1)
    {
        // Take all parts except last
        output = string.Join("", split.Take(split.Count()-1).ToArray());

        // Combine token parts with last part
        output = string.Format("{0}.{1}", output, split.Last());
    }

    // Parse double invariant
    double d = double.Parse(output, CultureInfo.InvariantCulture);
    Console.WriteLine(d);
}

2
1.234.567.890 จะกลับมา 1234567.890
Dan Vogel

ฉันยังไม่ได้ลอง แต่ถ้าคุณรันแอพในวัฒนธรรมที่แตกต่างกัน SOs รหัสนี้จะไม่เป็นการหลอกลวงฉันคิดว่า: /
Dani bISHOP

1

ฉันคิดว่าการแปลงที่ถูกต้อง 100% นั้นเป็นไปไม่ได้ถ้าค่านั้นมาจากการป้อนข้อมูลของผู้ใช้ เช่นถ้าค่าเป็น 123.456 ก็สามารถจัดกลุ่มหรืออาจเป็นจุดทศนิยม หากคุณต้องการ 100% จริงๆคุณต้องอธิบายรูปแบบของคุณและโยนข้อยกเว้นหากไม่ถูกต้อง

แต่ฉันปรับปรุงรหัสของ JanW ดังนั้นเราจะได้รับมากขึ้นอีกเล็กน้อยถึง 100% แนวคิดเบื้องหลังคือถ้าตัวคั่นสุดท้ายเป็น groupSeperator สิ่งนี้จะเป็นประเภทจำนวนเต็มมากกว่า double

รหัสเพิ่มเป็นในครั้งแรกถ้าของGetDouble

void Main()
{
    List<string> inputs = new List<string>() {
        "1.234.567,89",
        "1 234 567,89",
        "1 234 567.89",
        "1,234,567.89",
        "1234567,89",
        "1234567.89",
        "123456789",
        "123.456.789",
        "123,456,789,"
    };

    foreach(string input in inputs) {
        Console.WriteLine(GetDouble(input,0d));
    }

}

public static double GetDouble(string value, double defaultValue) {
    double result;
    string output;

    // Check if last seperator==groupSeperator
    string groupSep = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator;
    if (value.LastIndexOf(groupSep) + 4 == value.Count())
    {
        bool tryParse = double.TryParse(value, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, out result);
        result = tryParse ? result : defaultValue;
    }
    else
    {
        // Unify string (no spaces, only . )
        output = value.Trim().Replace(" ", string.Empty).Replace(",", ".");

        // Split it on points
        string[] split = output.Split('.');

        if (split.Count() > 1)
        {
            // Take all parts except last
            output = string.Join(string.Empty, split.Take(split.Count()-1).ToArray());

            // Combine token parts with last part
            output = string.Format("{0}.{1}", output, split.Last());
        }
        // Parse double invariant
        result = double.Parse(output, System.Globalization.CultureInfo.InvariantCulture);
    }
    return result;
}

1
        var doublePattern = @"(?<integer>[0-9]+)(?:\,|\.)(?<fraction>[0-9]+)";
        var sourceDoubleString = "03444,44426";
        var match = Regex.Match(sourceDoubleString, doublePattern);

        var doubleResult = match.Success ? double.Parse(match.Groups["integer"].Value) + (match.Groups["fraction"].Value == null ? 0 : double.Parse(match.Groups["fraction"].Value) / Math.Pow(10, match.Groups["fraction"].Value.Length)): 0;
        Console.WriteLine("Double of string '{0}' is {1}", sourceDoubleString, doubleResult);

0

แทนที่จะต้องระบุ locale ใน parses ทั้งหมดฉันต้องการตั้งค่า locale แบบกว้างของแอ็พพลิเคชันแม้ว่ารูปแบบสตริงจะไม่สอดคล้องกันในแอป แต่สิ่งนี้อาจไม่ทำงาน

CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("pt-PT");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("pt-PT");

การกำหนดสิ่งนี้เมื่อเริ่มต้นแอปพลิเคชันของคุณจะทำให้การแยกวิเคราะห์สองครั้งทั้งหมดคาดว่าเครื่องหมายจุลภาคเป็นตัวคั่นทศนิยม คุณสามารถตั้งค่าภาษาที่เหมาะสมเพื่อให้ทศนิยมและตัวคั่นหลักพันเหมาะสมกับสตริงที่คุณกำลังวิเคราะห์คำ


0

เป็นเรื่องยากโดยไม่ระบุตัวแยกทศนิยมที่ต้องการค้นหา แต่ถ้าคุณทำนี่คือสิ่งที่ฉันกำลังใช้:

    public static double Parse(string str, char decimalSep)
    {
        string s = GetInvariantParseString(str, decimalSep);
        return double.Parse(s, System.Globalization.CultureInfo.InvariantCulture);
    }

    public static bool TryParse(string str, char decimalSep, out double result)
    {
        // NumberStyles.Float | NumberStyles.AllowThousands got from Reflector
        return double.TryParse(GetInvariantParseString(str, decimalSep), NumberStyles.Float | NumberStyles.AllowThousands, System.Globalization.CultureInfo.InvariantCulture, out result);
    }

    private static string GetInvariantParseString(string str, char decimalSep)
    {
        str = str.Replace(" ", "");

        if (decimalSep != '.')
            str = SwapChar(str, decimalSep, '.');

        return str;
    }
    public static string SwapChar(string value, char from, char to)
    {
        if (value == null)
            throw new ArgumentNullException("value");

        StringBuilder builder = new StringBuilder();

        foreach (var item in value)
        {
            char c = item;
            if (c == from)
                c = to;
            else if (c == to)
                c = from;

            builder.Append(c);
        }
        return builder.ToString();
    }

    private static void ParseTestErr(string p, char p_2)
    {
        double res;
        bool b = TryParse(p, p_2, out res);
        if (b)
            throw new Exception();
    }

    private static void ParseTest(double p, string p_2, char p_3)
    {
        double d = Parse(p_2, p_3);
        if (d != p)
            throw new Exception();
    }

    static void Main(string[] args)
    {
        ParseTest(100100100.100, "100.100.100,100", ',');
        ParseTest(100100100.100, "100,100,100.100", '.');
        ParseTest(100100100100, "100.100.100.100", ',');
        ParseTest(100100100100, "100,100,100,100", '.');
        ParseTestErr("100,100,100,100", ',');
        ParseTestErr("100.100.100.100", '.');
        ParseTest(100100100100, "100 100 100 100.0", '.');
        ParseTest(100100100.100, "100 100 100.100", '.');
        ParseTest(100100100.100, "100 100 100,100", ',');
        ParseTest(100100100100, "100 100 100,100", '.');
        ParseTest(1234567.89, "1.234.567,89", ',');    
        ParseTest(1234567.89, "1 234 567,89", ',');    
        ParseTest(1234567.89, "1 234 567.89",     '.');
        ParseTest(1234567.89, "1,234,567.89",    '.');
        ParseTest(1234567.89, "1234567,89",     ',');
        ParseTest(1234567.89, "1234567.89",  '.');
        ParseTest(123456789, "123456789", '.');
        ParseTest(123456789, "123456789", ',');
        ParseTest(123456789, "123.456.789", ',');
        ParseTest(1234567890, "1.234.567.890", ',');
    }

สิ่งนี้น่าจะใช้ได้กับทุกวัฒนธรรม ไม่สามารถแยกวิเคราะห์สตริงที่มีตัวคั่นทศนิยมมากกว่าหนึ่งตัวได้อย่างถูกต้องซึ่งแตกต่างจากการนำไปใช้ที่แทนที่แทนที่จะสลับ


0

ฉันปรับปรุงรหัสของ @JanW เช่นกัน ...

ฉันต้องการมันเพื่อจัดรูปแบบผลลัพธ์จากเครื่องมือทางการแพทย์และพวกเขาก็ส่ง "> 1,000", "23.3e02", "350E-02" และ "เชิงลบ"

private string FormatResult(string vResult)
{
  string output;
  string input = vResult;

  // Unify string (no spaces, only .)
  output = input.Trim().Replace(" ", "").Replace(",", ".");

  // Split it on points
  string[] split = output.Split('.');

  if (split.Count() > 1)
  {
    // Take all parts except last
    output = string.Join("", split.Take(split.Count() - 1).ToArray());

    // Combine token parts with last part
    output = string.Format("{0}.{1}", output, split.Last());
  }
  string sfirst = output.Substring(0, 1);

  try
  {
    if (sfirst == "<" || sfirst == ">")
    {
      output = output.Replace(sfirst, "");
      double res = Double.Parse(output);
      return String.Format("{1}{0:0.####}", res, sfirst);
    }
    else
    {
      double res = Double.Parse(output);
      return String.Format("{0:0.####}", res);
    }
  }
  catch
  {
    return output;
  }
}

-2
System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.CurrentCulture;

string _pos = dblstr.Replace(".",
    ci.NumberFormat.NumberDecimalSeparator).Replace(",",
        ci.NumberFormat.NumberDecimalSeparator);

double _dbl = double.Parse(_pos);

-3

ฉันคิดว่ามันเป็นคำตอบที่ดีที่สุด:

public static double StringToDouble(string toDouble)
{
    toDouble = toDouble.Replace(",", "."); //Replace every comma with dot

    //Count dots in toDouble, and if there is more than one dot, throw an exception.
    //Value such as "123.123.123" can't be converted to double
    int dotCount = 0;
    foreach (char c in toDouble) if (c == '.') dotCount++; //Increments dotCount for each dot in toDouble
    if (dotCount > 1) throw new Exception(); //If in toDouble is more than one dot, it means that toCount is not a double

    string left = toDouble.Split('.')[0]; //Everything before the dot
    string right = toDouble.Split('.')[1]; //Everything after the dot

    int iLeft = int.Parse(left); //Convert strings to ints
    int iRight = int.Parse(right);

    //We must use Math.Pow() instead of ^
    double d = iLeft + (iRight * Math.Pow(10, -(right.Length)));
    return d;
}

อธิบายรหัสของคุณและให้รายละเอียดเพิ่มเติมจะเป็นประโยชน์
Charlie Fish

อะไรจะอธิบายที่นี่ ทุกอย่างอยู่ในความคิดเห็น
Endorphinex

-3

ด้านล่างมีประสิทธิภาพน้อยกว่า แต่ฉันใช้ตรรกะนี้ ค่านี้ใช้ได้ต่อเมื่อคุณมีตัวเลขสองหลักหลังจุดทศนิยม

double val;

if (temp.Text.Split('.').Length > 1)
{
    val = double.Parse(temp.Text.Split('.')[0]);

    if (temp.Text.Split('.')[1].Length == 1)
        val += (0.1 * double.Parse(temp.Text.Split('.')[1]));
    else
        val += (0.01 * double.Parse(temp.Text.Split('.')[1]));
}
else
    val = double.Parse(RR(temp.Text));

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.