C # Double - ToString () การจัดรูปแบบทศนิยมสองตำแหน่ง แต่ไม่มีการปัดเศษ


153

ฉันจะฟอร์แมต a เป็นDoublea Stringใน C # เพื่อให้มีทศนิยมสองตำแหน่งเท่านั้นได้อย่างไร

ถ้าฉันใช้String.Format("{0:0.00}%", myDoubleValue)จำนวนนั้นจะถูกปัดเศษและฉันต้องการตัดทอนแบบง่ายโดยไม่ต้องปัดเศษ ฉันยังต้องการให้การแปลงStringเป็นเรื่องละเอียดอ่อนทางวัฒนธรรม


"ไวต่อวัฒนธรรม" คุณหมายถึงอะไร? นั่นหมายความว่าผลลัพธ์ของการจัดรูปแบบต้องแตกต่างกันไปขึ้นอยู่กับค่าวัฒนธรรมที่โปรแกรมเมอร์จัดให้ หรือคุณต้องการใช้วัฒนธรรมใดก็ตามที่เป็นค่าเริ่มต้นสำหรับเธรดปัจจุบัน
CesarGon

คำตอบ:


204

ฉันใช้สิ่งต่อไปนี้:

double x = Math.Truncate(myDoubleValue * 100) / 100;

ตัวอย่างเช่น

หากหมายเลขคือ 50.947563 และคุณใช้สิ่งต่อไปนี้สิ่งต่อไปนี้จะเกิดขึ้น:

- Math.Truncate(50.947563 * 100) / 100;
- Math.Truncate(5094.7563) / 100;
- 5094 / 100
- 50.94

และมีคำตอบของคุณถูกตัดทอนตอนนี้การจัดรูปแบบสตริงเพียงทำต่อไปนี้:

string s = string.Format("{0:N2}%", x); // No fear of rounding and takes the default number format

3
-1 คุณสามารถทำการจัดรูปแบบที่ไวต่อวัฒนธรรมในstring.Formatขั้นตอนเดียวกับที่จัดรูปแบบสตริง ดูคำตอบของฉันด้านล่าง
CesarGon

1
เยี่ยมมาก ฉันหวังว่าความคิดเห็นของฉันไม่ได้ดูโง่ ๆ ในตอนนี้ :-) ฉันจะเปลี่ยน downvote ของฉันแล้ว
CesarGon

1
สำหรับฉันแล้วมันเป็นวิธีการแก้ปัญหาในการจัดรูปแบบสตริงง่ายอย่างไม่น่าเชื่อการตัดทอนมีความซับซ้อนมากขึ้น
Kyle Rosendo

1
น่าเสียดายที่โซลูชันของคุณไม่ทำงานเมื่อจำนวนน้อยกว่า 1 เพื่ออธิบาย: 0.97 มีวิธีแก้ปัญหาสำหรับสถานการณ์นี้หรือไม่
Ali Dehghan

2
@ จอนนี่ที่ไม่ทำงานเพราะรอบ - OP ต้องการให้ตัดทอน (และไม่ปัด) ความแตกต่างนั้นลึกซึ้ง
BKSpurgeon

102

ต่อไปนี้รอบตัวเลข แต่แสดงให้เห็นถึงทศนิยม 2 ตำแหน่ง (ลบเลขศูนย์ต่อท้าย) .##ขอบคุณ

decimal d0 = 24.154m;
decimal d1 = 24.155m;
decimal d2 = 24.1m;
decimal d3 = 24.0m;

d0.ToString("0.##");   //24.15
d1.ToString("0.##");   //24.16 (rounded up)
d2.ToString("0.##");   //24.1  
d3.ToString("0.##");   //24

http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/


12
มันใช้งานไม่ได้ ลองกับ 0.2415999 โซลูชันนี้จะปัดเศษไม่ใช่ตัดทอน
BJury

5
ว้าวโหวตมาก ๆ แต่ก็ใช้การปัดเศษ อาจจำเป็นต้องชี้ให้เห็นว่าการปัดเศษมุ่งไปยังตำแหน่งทศนิยมที่ใกล้ที่สุดที่ร้องขอในขณะที่การตัดจะถูกตัดออกหลังจากตำแหน่งทศนิยมที่ใกล้ที่สุดร้องขอ
mysticcoder

1
@magiccoder ฉันคิดว่าคำตอบของฉันได้รับ upvotes มากมายเพราะพวกเขามาถึงคำถาม ops ในการค้นหาของ Google ในแบบเดียวกับที่ฉันทำมองหาการลบเลขศูนย์ต่อท้ายและไม่ต้องการความต้องการในการปัดเศษคำถาม ผมคิดว่าผมควรลบคำตอบของฉัน ...
ไบรอันอ็อกเดน

@BrianOgden - ไม่โปรดอย่าลบ ฉันมาที่นี่เพื่อค้นหาคำตอบของคุณ +1
Roberto

35

ฉันขอแนะนำให้คุณตัดทอนก่อนจากนั้นจึงจัดรูปแบบ:

double a = 123.4567;
double aTruncated = Math.Truncate(a * 100) / 100;
CultureInfo ci = new CultureInfo("de-DE");
string s = string.Format(ci, "{0:0.00}%", aTruncated);

ใช้ค่าคงที่ 100 สำหรับการตัด 2 หลัก ใช้ 1 ตามด้วยศูนย์ให้มากที่สุดเท่าตัวเลขหลังจุดทศนิยมที่คุณต้องการ ใช้ชื่อวัฒนธรรมที่คุณต้องการปรับผลการจัดรูปแบบ


ฉันคิดว่าแทนที่จะเป็นnew CultureInfo("de-DE")คุณควรใช้คุณสมบัติคงที่Culture.InvariantCulture
vchan



6

ฟังก์ชั่น c # ตามที่แสดงออกโดย Kyle Rozendo:

string DecimalPlaceNoRounding(double d, int decimalPlaces = 2)
{
    d = d * Math.Pow(10, decimalPlaces);
    d = Math.Truncate(d);
    d = d / Math.Pow(10, decimalPlaces);
    return string.Format("{0:N" + Math.Abs(decimalPlaces) + "}", d);
}

5

วิธีการเกี่ยวกับการเพิ่มทศนิยมพิเศษที่จะถูกปัดเศษแล้วละทิ้ง:

var d = 0.241534545765;
var result1 = d.ToString("0.###%");

var result2 = result1.Remove(result1.Length - 1);

3
มันตลกดีที่คำตอบที่ไม่ทำงานมี 60 โหวต (ณ วันนี้) และวิธีการแก้ปัญหาที่ง่ายและกันกระสุนนี้มีเพียงหนึ่งเดียวเท่านั้น ....
Arthur Kazykhanov

5
สิ่งนี้จะไม่ทำงานในกรณีที่การปัดเศษส่งผลกระทบมากกว่าหนึ่งหลักเหนือทางลัด ตัวอย่างเช่น 0.199999 จะสิ้นสุดที่ 0.20 ด้วยรหัสนี้แทน 0.19
Bernem

4

มันใช้งานได้สำหรับฉัน

string prouctPrice = Convert.ToDecimal(String.Format("{0:0.00}", Convert.ToDecimal(yourString))).ToString();

2

ฉันรู้ว่านี่เป็นหัวข้อเก่า แต่ฉันต้องทำเช่นนี้ string.formatในขณะที่อีกแนวทางที่นี่ทำงานผมอยากเป็นวิธีที่ง่ายที่จะสามารถส่งผลกระทบต่อมากโทรไป ดังนั้นการเพิ่มการเรียกMath.Truncateเข้าทั้งหมดจึงไม่ใช่ตัวเลือกที่ดีจริงๆ นอกจากนี้เนื่องจากการจัดรูปแบบบางอย่างถูกเก็บไว้ในฐานข้อมูลทำให้ยิ่งแย่ลง

ดังนั้นฉันทำผู้ให้บริการรูปแบบที่กำหนดเองซึ่งจะทำให้ฉันสามารถเพิ่มการตัดทอนลงในสตริงการจัดรูปแบบเช่น:

string.format(new FormatProvider(), "{0:T}", 1.1299); // 1.12
string.format(new FormatProvider(), "{0:T(3)", 1.12399); // 1.123
string.format(new FormatProvider(), "{0:T(1)0,000.0", 1000.9999); // 1,000.9

การใช้งานนั้นค่อนข้างง่ายและสามารถขยายได้อย่างง่ายดายตามข้อกำหนดอื่น ๆ

public class FormatProvider : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType)
    {
        if (formatType == typeof (ICustomFormatter))
        {
            return this;
        }
        return null;
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        if (arg == null || arg.GetType() != typeof (double))
        {
            try
            {
                return HandleOtherFormats(format, arg);
            }
            catch (FormatException e)
            {
                throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
            }
        }

        if (format.StartsWith("T"))
        {
            int dp = 2;
            int idx = 1;
            if (format.Length > 1)
            {
                if (format[1] == '(')
                {
                    int closeIdx = format.IndexOf(')');
                    if (closeIdx > 0)
                    {
                        if (int.TryParse(format.Substring(2, closeIdx - 2), out dp))
                        {
                            idx = closeIdx + 1;
                        }
                    }
                    else
                    {
                        throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
                    }
                }
            }
            double mult = Math.Pow(10, dp);
            arg = Math.Truncate((double)arg * mult) / mult;
            format = format.Substring(idx);
        }

        try
        {
            return HandleOtherFormats(format, arg);
        }
        catch (FormatException e)
        {
            throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
        }
    }

    private string HandleOtherFormats(string format, object arg)
    {
        if (arg is IFormattable)
        {
            return ((IFormattable) arg).ToString(format, CultureInfo.CurrentCulture);
        }
        return arg != null ? arg.ToString() : String.Empty;
    }
}


1

สำหรับสิ่งที่มีค่าสำหรับการแสดงสกุลเงินคุณสามารถใช้"C":

double cost = 1.99;
m_CostText.text = cost.ToString("C"); /*C: format as currentcy */

เอาท์พุท: $1.99


0

คุณยังสามารถเขียนIFormatProviderของคุณเองได้แม้ว่าฉันคิดว่าในที่สุดคุณก็ต้องคิดถึงวิธีการตัดทอน

.NET Framework ยังสนับสนุนการจัดรูปแบบที่กำหนดเอง นี้มักจะเกี่ยวข้องกับการสร้างคลาสการจัดรูปแบบการดำเนินการที่ทั้งสอง IFormatProvider และICustomFormatter (MSDN)

อย่างน้อยมันก็สามารถนำมาใช้ใหม่ได้อย่างง่ายดาย

มีบทความเกี่ยวกับวิธีการใช้ IFormatProvider ของคุณเอง / ICustomFormatter เป็นที่นี่ที่ CodeProject ในกรณีนี้ "การขยาย" รูปแบบตัวเลขที่มีอยู่อาจเป็นทางออกที่ดีที่สุด ดูไม่ยากเกินไป


0

ต่อไปนี้สามารถใช้สำหรับการแสดงผลเท่านั้นซึ่งใช้คุณสมบัติของ String ..

double value = 123.456789;
String.Format("{0:0.00}", value);

สิ่งนี้จะให้ "123.46" คำถามนี้ถามโดยเฉพาะว่าไม่มีการปัดเศษ
Tobberoth

0

สารละลาย:

var d = 0.123345678; 
var stringD = d.ToString(); 
int indexOfP = stringD.IndexOf("."); 
var result = stringD.Remove((indexOfP+1)+2);

(indexOfP + 1) +2 (ตัวเลขนี้ขึ้นอยู่กับจำนวนที่คุณต้องการเก็บไว้ฉันให้ทั้งสองเพราะเจ้าของคำถามต้องการ)


0

นอกจากนี้ยังสังเกตข้อมูลCultureInformationของระบบของคุณ นี่คือทางออกของฉันโดยไม่ต้องปัดเศษ

ในตัวอย่างนี้คุณเพียงแค่ต้องกำหนดตัวแปรMyValueเป็นสองเท่า ดังนั้นคุณจะได้รับค่าการจัดรูปแบบของคุณในตัวแปรสตริงNewValue NewValue

หมายเหตุ - ตั้งค่า C # โดยใช้ข้อความสั่ง:

using System.Globalization;  

string MyFormat = "0";
if (MyValue.ToString (CultureInfo.InvariantCulture).Contains (CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator))
   {
      MyFormat += ".00";
   }

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