C # Double - Format ToString () dengan dua tempat desimal tetapi tanpa pembulatan


153

Bagaimana cara memformat a Doubleke Stringdalam C # sehingga hanya memiliki dua tempat desimal?

Jika saya menggunakan String.Format("{0:0.00}%", myDoubleValue)angka maka dibulatkan dan saya ingin memotong sederhana tanpa pembulatan. Saya juga ingin konversi Stringmenjadi peka terhadap budaya.


Apa yang Anda maksud dengan "sensitif budaya"? Apakah itu berarti bahwa hasil pemformatan harus bervariasi tergantung pada nilai budaya yang disediakan programmer? Atau Anda ingin menggunakan budaya apa pun yang merupakan default untuk utas saat ini?
CesarGon

Jawaban:


204

Saya menggunakan yang berikut ini:

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

Misalnya:

Jika jumlahnya 50,947563 dan Anda menggunakan yang berikut, yang berikut ini akan terjadi:

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

Dan ada jawaban Anda yang terpotong, sekarang untuk memformat string cukup lakukan hal berikut:

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

3
-1 Anda bisa melakukan pemformatan yang peka terhadap budaya pada string.Formatlangkah yang sama dengan memformat string. Lihat jawaban saya di bawah ini.
CesarGon

1
Itu hebat. Saya harap komentar saya tidak terlihat konyol sekarang. :-) Saya akan mengubah downvote saya kalau begitu.
CesarGon

1
Bagi saya itu, karena solusi pada pemformatan string sangat sederhana, pemotongan lebih rumit.
Kyle Rosendo

1
Sayangnya solusi Anda tidak berhasil ketika angkanya kurang dari 1, untuk menggambarkan: 0,97, Apakah ada solusi untuk situasi ini?
Ali Dehghan

2
@ Jonny itu tidak akan berfungsi karena itu bulat - OP ingin itu terpotong (dan tidak bulat). Perbedaannya halus.
BKSpurgeon

102

Angka -angka berikut ini membulatkan angka, tetapi hanya menampilkan hingga 2 tempat desimal (menghilangkan sembarang angka nol), terima kasih .##.

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
Ini tidak berhasil. Cobalah dengan 0.2415999. Solusi ini berputar, bukan terpotong.
BJury

5
Wow, begitu banyak suara tetapi menggunakan pembulatan. Mungkin perlu untuk menunjukkan bahwa pembulatan menuju ke tempat desimal terdekat yang diminta, sedangkan pemotongan dipotong setelah tempat desimal terdekat yang diminta.
mysticcoder

1
@ mysticcoder Saya kira jawaban saya mendapatkan begitu banyak upvotes karena mereka datang ke pertanyaan ops di pencarian Google dengan cara yang sama saya lakukan, mencari untuk menghapus nol di belakang, dan tidak mencari keinginan bulat dari pertanyaan ops. Saya kira saya harus menghapus jawaban saya ...
Brian Ogden

@BrianOgden - Tidak, tolong jangan hapus. Saya tiba di sini mencari jawaban Anda. +1
Roberto

35

Saya sarankan Anda memotong dulu, lalu format:

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);

Gunakan konstanta 100 untuk 2 digit terpotong; gunakan angka 1 diikuti angka nol setelah angka desimal yang Anda inginkan. Gunakan nama budaya yang Anda butuhkan untuk menyesuaikan hasil pemformatan.


Saya berpikir bahwa alih-alih new CultureInfo("de-DE"), Anda harus menggunakan properti statisCulture.InvariantCulture
vchan


13

saya gunakan price.ToString("0.00") untuk mendapatkan 0s terkemuka


6

Fungsi c #, seperti yang diungkapkan oleh 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

Bagaimana dengan menambahkan satu desimal tambahan yang dibulatkan dan kemudian dibuang:

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

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

3
Sangat lucu bagaimana jawaban yang tidak berfungsi memiliki 60 suara (hingga hari ini), dan solusi yang cukup sederhana dan anti peluru ini hanya memiliki satu ....
Arthur Kazykhanov

5
Ini tidak akan berfungsi jika pembulatan mempengaruhi lebih dari satu digit di atas cutoff. Misalnya 0,199999 akan berakhir sebagai 0,20 dengan kode ini, bukan 0,19.
Bernem

4

Ini bekerja untuk saya

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

2

Saya tahu ini adalah utas lama tetapi saya hanya harus melakukan ini. Sementara pendekatan lain di sini berfungsi, saya ingin cara mudah untuk dapat memengaruhi banyak panggilan string.format. Jadi menambahkan Math.Truncatesemua panggilan tidak benar-benar pilihan yang baik. Juga karena beberapa format disimpan dalam database, itu membuatnya lebih buruk.

Jadi, saya membuat penyedia format kustom yang memungkinkan saya untuk menambahkan pemotongan ke string pemformatan, misalnya:

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

Implementasinya cukup sederhana dan mudah diperluas ke persyaratan lain.

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;
    }
}

2

Saya punya masalah dengan Formulir Xamarin dan menyelesaikannya dengan ini:

percent.ToString("0.##"+"%")

1

Untuk nilai apa, untuk menunjukkan mata uang, Anda dapat menggunakan "C":

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

Keluaran: $1.99


0

Anda juga bisa menulis IFormatProvider Anda sendiri , meskipun saya kira pada akhirnya Anda harus memikirkan cara untuk melakukan pemotongan yang sebenarnya.

.NET Framework juga mendukung pemformatan khusus. Ini biasanya melibatkan pembuatan kelas pemformatan yang mengimplementasikan IFormatProvider dan ICustomFormatter . (msdn)

Setidaknya itu akan mudah digunakan kembali.

Ada artikel tentang cara menerapkan IFormatProvider / ICustomFormatter Anda sendiri di sini di CodeProject . Dalam hal ini, "memperluas" format numerik yang ada mungkin merupakan taruhan terbaik. Itu tidak terlihat terlalu sulit.


0

Mengikuti dapat digunakan hanya untuk tampilan yang menggunakan properti String ..

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

Ini akan menghasilkan "123,46". Pertanyaannya secara khusus tidak meminta pembulatan.
Tobberoth

0

Larutan:

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

(indexOfP + 1) +2 (angka ini tergantung pada berapa banyak angka yang ingin Anda pertahankan. Saya berikan dua karena pemilik pertanyaan ingin.)


0

Perhatikan juga Informasi Budaya sistem Anda. Di sini solusi saya tanpa pembulatan.

Dalam contoh ini Anda hanya perlu mendefinisikan variabel MyValue sebagai ganda. Akibatnya, Anda mendapatkan nilai yang diformat dalam variabel string NewValue .

Catatan - Juga mengatur pernyataan menggunakan C #:

using System.Globalization;  

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

string NewValue = MyValue.ToString(MyFormat);
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.