ฉันต้องการแยกวิเคราะห์สตริง "1.2345E-02" (ตัวเลขที่แสดงในสัญกรณ์เอกซ์โพเนนเชียล) เป็นประเภทข้อมูลทศนิยม แต่Decimal.Parse("1.2345E-02")
เพียงแค่แสดงข้อผิดพลาด
ฉันต้องการแยกวิเคราะห์สตริง "1.2345E-02" (ตัวเลขที่แสดงในสัญกรณ์เอกซ์โพเนนเชียล) เป็นประเภทข้อมูลทศนิยม แต่Decimal.Parse("1.2345E-02")
เพียงแค่แสดงข้อผิดพลาด
คำตอบ:
มันเป็นเลขทศนิยมคุณต้องบอกมันว่า:
decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);
ใช้งานได้หากคุณระบุNumberStyles.Float
:
decimal x = decimal.Parse("1.2345E-02", NumberStyles.Float);
Console.WriteLine(x); // Prints 0.012345
ฉันไม่แน่ใจว่าทำไมจึงไม่รองรับโดยค่าเริ่มต้นค่าเริ่มต้นคือการใช้NumberStyles.Number
ซึ่งใช้รูปแบบ AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowTrailingSign, AllowDecimalPoint และ AllowTh thousands อาจเกี่ยวข้องกับประสิทธิภาพ การระบุเลขชี้กำลังค่อนข้างหายากฉันคิดว่า
decimal
ด้วยdouble
ในรหัสของฉันทำงานได้ดีสำหรับฉันเช่นเดียวกับที่ฉันคาดหวังไว้ หากคุณสามารถให้รายละเอียดเกี่ยวกับสิ่งที่คุณกำลังพยายามรหัสที่คุณใช้และผลลัพธ์ก็จะช่วยได้ง่ายกว่ามาก
นอกเหนือจากการระบุ NumberStyles แล้วฉันขอแนะนำให้คุณใช้ฟังก์ชันdecimal.TryParseเช่น:
decimal result;
if( !decimal.TryParse("1.2345E-02", NumberStyles.Any, CultureInfo.InvariantCulture, out result) )
{
// do something in case it fails?
}
เป็นอีกทางเลือกหนึ่งของ NumberStyles คุณสามารถใช้ชุดเฉพาะได้หากคุณต้องการรูปแบบของคุณ เช่น:
NumberStyles.AllowExponent | NumberStyles.Float
decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);
ระมัดระวังเกี่ยวกับคำตอบที่เลือก: มีความละเอียดอ่อนที่ระบุSystem.Globalization.NumberStyles ลอยในรูปทศนิยมซึ่งอาจนำไปสู่System.FormatExceptionเนื่องจากระบบของคุณอาจรอตัวเลขที่จัดรูปแบบด้วย ',' แทนที่จะเป็น ''
ตัวอย่างเช่นในรูปแบบภาษาฝรั่งเศส "1.2345E-02" ไม่ถูกต้องคุณต้องแปลงเป็น "1,2345E-02" ก่อน
โดยสรุปให้ใช้บางสิ่งตามแนวของ:
Decimal.Parse(valueString.Replace('.',','), System.Globalization.NumberStyles.Float);
ฉันพบว่าNumberStyles.Float
ในบางกรณีการส่งผ่านจะเปลี่ยนกฎที่ใช้ประมวลผลสตริงและผลลัพธ์ในผลลัพธ์ที่แตกต่างจากNumberStyles.Number
(กฎเริ่มต้นที่ใช้โดยdecimal.Parse
)
ตัวอย่างเช่นรหัสต่อไปนี้จะสร้างFormatException
ในเครื่องของฉัน:
CultureInfo culture = new CultureInfo("");
culture.NumberFormat.NumberDecimalDigits = 2;
culture.NumberFormat.NumberDecimalSeparator = ".";
culture.NumberFormat.NumberGroupSeparator = ",";
Decimal.Parse("1,234.5", NumberStyles.Float, culture); // FormatException thrown here
ฉันขอแนะนำให้ใช้อินพุตNumberStyles.Number | NumberStyles.AllowExponent
เนื่องจากจะอนุญาตให้ใช้เลขเอกซ์โพเนนเชียลและจะยังคงประมวลผลสตริงภายใต้decimal
กฎ
CultureInfo culture = new CultureInfo("");
culture.NumberFormat.NumberDecimalDigits = 2;
culture.NumberFormat.NumberDecimalSeparator = ".";
culture.NumberFormat.NumberGroupSeparator = ",";
Decimal.Parse("1,234.5",NumberStyles.Number | NumberStyles.AllowExponent, culture); // Does not generate a FormatException
ในการตอบคำถามของผู้โพสต์คำตอบที่ถูกต้องควรเป็น:
decimal x = decimal.Parse("1.2345E-02", NumberStyles.Number | NumberStyles.AllowExponent);
Console.WriteLine(x);
คำเตือนเกี่ยวกับการใช้ NumberStyles ใด ๆ :
"6.33E + 03" แปลงเป็น 6330 ตามที่คาดไว้ ในภาษาเยอรมันจุดทศนิยมจะแสดงด้วยลูกน้ำ แต่ 6,33E + 03 จะแปลงเป็น 633000! นี่เป็นปัญหาสำหรับลูกค้าของฉันเนื่องจากไม่ทราบวัฒนธรรมที่สร้างข้อมูลและอาจแตกต่างจากวัฒนธรรมที่ดำเนินการกับข้อมูล ในกรณีของฉันฉันมีสัญกรณ์ทางวิทยาศาสตร์เสมอดังนั้นฉันจึงสามารถแทนที่ลูกน้ำเป็นจุดทศนิยมได้เสมอก่อนที่จะแยกวิเคราะห์ แต่ถ้าคุณกำลังทำงานกับตัวเลขตามอำเภอใจเช่นตัวเลขที่จัดรูปแบบสวย ๆ เช่น 1,234,567 วิธีนั้นก็ไม่ได้ผล
คุณไม่จำเป็นต้องแทนที่จุด (ตามลำดับลูกน้ำ) เพียงระบุอินพุต IFormatProvider:
float d = Single.Parse("1.27315", System.Globalization.NumberStyles.Float, new CultureInfo("en-US"));
float d = Single.Parse("1,27315", System.Globalization.NumberStyles.Float, new CultureInfo("de-DE"));
หากคุณต้องการตรวจสอบและแปลงค่าเลขชี้กำลังให้ใช้สิ่งนี้
string val = "1.2345E-02";
double dummy;
bool hasExponential = (val.Contains("E") || val.Contains("e")) && double.TryParse(val, out dummy);
if (hasExponential)
{
decimal d = decimal.Parse(val, NumberStyles.Float);
}
หวังว่านี่จะช่วยใครบางคนได้
เริ่มต้นNumberStyle
สำหรับการdecimal.Parse(String)
มีดังนั้นถ้าคุณเพียงต้องการที่จะเพิ่มฟังก์ชันการทำงานเพื่อให้เลขชี้กำลังแล้วคุณสามารถทำบิตหรือจะรวมถึงNumberStyles.Number
NumberStyles.AllowExponent
decimal d = decimal
.Parse("1.2345E-02", NumberStyles.Number | NumberStyles.AllowExponent);