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.

kjv
sumber
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
Kyle Rosendo
sumber
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/

Brian Ogden
sumber
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.

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

Metode paling sederhana, gunakan string format numerik:

double total = "43.257"
MessageBox.Show(total.ToString("F"));
Harambe Attack Helicopter
sumber
2
Sebenarnya metode ini membulatkan msdn.microsoft.com/en-us/library/…
elvin
13

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

CMS
sumber
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);
}
maks
sumber
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);

sumber
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();
Zain Ali
sumber
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;
    }
}
BJury
sumber
2

Saya punya masalah dengan Formulir Xamarin dan menyelesaikannya dengan ini:

percent.ToString("0.##"+"%")
Diego Sanchez
sumber
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

Roozbeh Zabihollahi
sumber
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.

Benny Jobigan
sumber
0

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

double value = 123.456789;
String.Format("{0:0.00}", value);
Md. Shafiqur Rahman
sumber
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.)

劉鎮 瑲
sumber
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);
Daniel
sumber