Bagaimana cara membulatkan nilai desimal ke 2 tempat desimal (untuk output pada halaman)


649

Saat menampilkan nilai desimal saat ini .ToString(), akurat untuk menyukai 15 tempat desimal, dan karena saya menggunakannya untuk mewakili dolar dan sen, saya hanya ingin output menjadi 2 tempat desimal.

Apakah saya menggunakan variasi .ToString()untuk ini?

Jawaban:


911
decimalVar.ToString ("#.##"); // returns "" when decimalVar == 0

atau

decimalVar.ToString ("0.##"); // returns "0"  when decimalVar == 0

31
masalahnya di sini adalah ketika kita memiliki 0,00; mengembalikan string kosong.
Jronny

164
Maka Anda bisa melakukan decimalVar.ToString ("0. ##"). Anda juga dapat menggunakan 0,00 sebagai string pemformatan.
albertein

54
Dengan solusi ini, Anda tidak akan memiliki format budaya yang diharapkan saat membaca angka. Untuk ini, Anda harus menggunakan ToString ("N2"), atau ToString ("N").
Shautieh

2
@Hill Decimaldan Doubleketik ToStringmetode menerima argumen untuk pemformatan. Coba konversi nilai Anda ke Desimal / Double terlebih dahulu.
sohaiby

1
@ f470071 Desimal adalah tipe nilai dan karenanya tidak pernah "dimodifikasi". Apapun, ToString () tidak pernah diharapkan untuk mengubah konten apa pun yang dipanggil.
Justin Skiles

590

Saya tahu ini adalah pertanyaan lama, tetapi saya terkejut melihat bahwa tidak ada yang mengirim jawaban itu;

  1. Tidak menggunakan pembulatan bankir
  2. Tidak menyimpan nilai sebagai desimal.

Inilah yang akan saya gunakan:

decimal.Round(yourValue, 2, MidpointRounding.AwayFromZero);

http://msdn.microsoft.com/en-us/library/9s0xa85y.aspx


3
ToString atau string.Format tidak menggunakan pembulatan bankir: msdn.microsoft.com/en-us/library/0c899ak8.aspx#sectionToggle1
Matthijs Wessels

1
@MatthijsWessels saya tahu ... tapi itu tidak menjaga nilainya sebagai desimal.
Mike M.

1
Ini adalah cara yang lebih baik untuk benar-benar mewakili dua tempat desimal karena tidak akan menghapus angka nol.
LiquidDrummer

355
decimalVar.ToString("F");

Ini akan:

  • Membulatkan ke 2 tempat desimal misalnya. 23.45623.46
  • Pastikan selalu ada 2 tempat desimal misalnya. 2323.00; 12.512.50

Ideal untuk menampilkan mata uang.

Lihatlah dokumentasi di ToString ("F") (terima kasih kepada Jon Schneider).


10
Ini berfungsi dengan baik ketika hanya memiliki 1 desimal; .ToString ("#. ##") gagal. Jawaban ini jauh lebih baik
Eric Frick

2
Bukankah putaran 23.456 => 23.46?
rtpHarry

14
Dokumentasi tentang apa yang dimaksud dengan "F" di sini, dan cara kerjanya: msdn.microsoft.com/en-us/library/…
Jon Schneider

4
Kenapa tidak .ToString ("N") bukannya "F"? Menurut pemahaman saya, mereka berdua akan bekerja untuk kebutuhan pertanyaan ini, tetapi N juga akan memberikan koma dalam jumlah ribuan.
jgerman

Catatan: .Mungkin diganti dengan ,berdasarkan budaya. Anda harus menyampaikan CultureInfo.InvariantCultureargumen kedua untuk menonaktifkan ini.
Duncan Luk


56

Diberikan desimal d = 12,345; ekspresi d.ToString ("C") atau String.Format ("{0: C}", d) menghasilkan $ 12,35 - perhatikan bahwa pengaturan mata uang budaya saat ini termasuk simbol digunakan.

Perhatikan bahwa "C" menggunakan jumlah digit dari kultur saat ini. Anda selalu dapat mengesampingkan standar untuk memaksa presisi yang diperlukan dengan C{Precision specifier}sejenisnya String.Format("{0:C2}", 5.123d).


4
@ Slick86 - tanda sekarang
fubo

48

Jika Anda ingin itu diformat dengan koma serta titik desimal (tetapi tidak ada simbol mata uang), seperti 3,456.789,12 ...

decimalVar.ToString("n2");

1
Jawaban yang lebih baik karena pertanyaannya adalah tentang menghasilkan pada halaman, dan pemformatan angka penting untuk angka besar. Juga, "n *" memperhitungkan budaya saat ini, sehingga bisa jadi "3.456.789,12", "3 456 789,12", dll.
Shautieh

29

Sudah ada dua jawaban skor tinggi yang merujuk ke Desimal. Putaran (...) tapi saya pikir sedikit lebih banyak penjelasan diperlukan - karena ada sifat penting tak terduga dari Desimal yang tidak jelas.

Desimal 'tahu' berapa banyak tempat desimal yang didasarkan pada dari mana asalnya.

Misalnya, hal-hal berikut mungkin tidak terduga:

Decimal.Parse("25").ToString()          =>   "25"
Decimal.Parse("25.").ToString()         =>   "25"
Decimal.Parse("25.0").ToString()        =>   "25.0"
Decimal.Parse("25.0000").ToString()     =>   "25.0000"

25m.ToString()                          =>   "25"
25.000m.ToString()                      =>   "25.000"

Melakukan operasi yang sama dengan tidak Doubleakan memberikan tempat desimal ( "25") untuk masing-masing di atas.

Ketika Anda ingin desimal ke 2 tempat desimal, ada kemungkinan 95% karena mata uangnya dalam hal ini mungkin baik untuk 95% waktu:

Decimal.Parse("25.0").ToString("c")     =>   "$25.00"

Atau di XAML yang baru saja Anda gunakan {Binding Price, StringFormat=c}

Satu kasus saya berlari ke tempat saya membutuhkan AS desimal desimal adalah ketika mengirim XML ke layanan web Amazon. Layanan ini mengeluh karena nilai Desimal (berasal dari SQL Server) dikirim sebagai 25.1200dan ditolak, ( 25.12adalah format yang diharapkan).

Yang perlu saya lakukan adalah Decimal.Round(...)dengan 2 tempat desimal untuk memperbaiki masalah.

 // This is an XML message - with generated code by XSD.exe
 StandardPrice = new OverrideCurrencyAmount()
 {
       TypedValue = Decimal.Round(product.StandardPrice, 2),
       currency = "USD"
 }

TypedValueadalah tipe Decimaljadi saya tidak bisa hanya melakukan ToString("N2")dan perlu untuk memutarnya dan menyimpannya sebagai decimal.


5
+1 ini adalah jawaban yang bagus. Ketika Anda mengatakan bahwa System.Decimal "tahu berapa banyak tempat desimal yang dimiliki" - istilahnya adalah System.Decimal tidak menormalisasi sendiri seperti tipe floating point lainnya. Properti lain yang berguna dari System.Decimal adalah bahwa hasil operasi matematika selalu memiliki jumlah tempat desimal tertinggi dari argumen input yaitu. 1,0 m + 2.000 m = 3.000 m . Anda dapat menggunakan fakta ini untuk memaksa desimal tanpa tempat desimal ke 2 tempat desimal hanya dengan mengalikannya dengan 1,00 m misalnya. 10m * 1,00m = 10.00m .
MattDavey

2
MattDavey salah, ketepatan desimal ditambahkan. (1.0m * 1.00m) .ToString () = "1.000"
Kaido

2
Sangat, sangat berguna untuk mengetahui bahwa "Sebuah desimal 'tahu' berapa banyak tempat desimal yang didasarkan pada dari mana asalnya." Terima kasih banyak!
iheartcsharp

21

Berikut ini adalah program Linqpad kecil untuk menampilkan berbagai format:

void Main()
{
    FormatDecimal(2345.94742M);
    FormatDecimal(43M);
    FormatDecimal(0M);
    FormatDecimal(0.007M);
}

public void FormatDecimal(decimal val)
{
    Console.WriteLine("ToString: {0}", val);
    Console.WriteLine("c: {0:c}", val);
    Console.WriteLine("0.00: {0:0.00}", val);
    Console.WriteLine("0.##: {0:0.##}", val);
    Console.WriteLine("===================");
}

Inilah hasilnya:

ToString: 2345.94742
c: $2,345.95
0.00: 2345.95
0.##: 2345.95
===================
ToString: 43
c: $43.00
0.00: 43.00
0.##: 43
===================
ToString: 0
c: $0.00
0.00: 0.00
0.##: 0
===================
ToString: 0.007
c: $0.01
0.00: 0.01
0.##: 0.01
===================


11

Sangat jarang Anda menginginkan string kosong jika nilainya 0.

decimal test = 5.00;
test.ToString("0.00");  //"5.00"
decimal? test2 = 5.05;
test2.ToString("0.00");  //"5.05"
decimal? test3 = 0;
test3.ToString("0.00");  //"0.00"

Jawaban berperingkat teratas adalah salah dan menghabiskan 10 menit waktu (kebanyakan) orang.


1
pada dasarnya "#"berarti digit angka (jika perlu) (tanpa padding jika tidak diperlukan) "0"berarti digit angka (tanpa mater apa pun) (diisi dengan nol jika tidak tersedia)
Mr Heelis

10

Jawaban Mike M. sempurna bagi saya di .NET, tetapi .NET Core tidak memiliki decimal.Roundmetode pada saat penulisan.

Di .NET Core, saya harus menggunakan:

decimal roundedValue = Math.Round(rawNumber, 2, MidpointRounding.AwayFromZero);

Metode peretasan, termasuk konversi ke string, adalah:

public string FormatTo2Dp(decimal myNumber)
{
    // Use schoolboy rounding, not bankers.
    myNumber = Math.Round(myNumber, 2, MidpointRounding.AwayFromZero);

    return string.Format("{0:0.00}", myNumber);
}

9

Tidak ada yang melakukan apa yang saya butuhkan, untuk memaksa 2 dp dan dibulatkan menjadi0.005 -> 0.01

Memaksa 2 dp membutuhkan peningkatan presisi sebesar 2 dp untuk memastikan kami memiliki setidaknya 2 dp

kemudian pembulatan untuk memastikan kita tidak memiliki lebih dari 2 dp

Math.Round(exactResult * 1.00m, 2, MidpointRounding.AwayFromZero)

6.665m.ToString() -> "6.67"

6.6m.ToString() -> "6.60"

9

Jawaban berperingkat teratas menjelaskan metode untuk memformat representasi string dari nilai desimal, dan itu berfungsi.

Namun, jika Anda benar-benar ingin mengubah presisi yang disimpan ke nilai aktual, Anda perlu menulis sesuatu seperti berikut:

public static class PrecisionHelper
{
    public static decimal TwoDecimalPlaces(this decimal value)
    {
        // These first lines eliminate all digits past two places.
        var timesHundred = (int) (value * 100);
        var removeZeroes = timesHundred / 100m;

        // In this implementation, I don't want to alter the underlying
        // value.  As such, if it needs greater precision to stay unaltered,
        // I return it.
        if (removeZeroes != value)
            return value;

        // Addition and subtraction can reliably change precision.  
        // For two decimal values A and B, (A + B) will have at least as 
        // many digits past the decimal point as A or B.
        return removeZeroes + 0.01m - 0.01m;
    }
}

Contoh uji unit:

[Test]
public void PrecisionExampleUnitTest()
{
    decimal a = 500m;
    decimal b = 99.99m;
    decimal c = 123.4m;
    decimal d = 10101.1000000m;
    decimal e = 908.7650m

    Assert.That(a.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("500.00"));

    Assert.That(b.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("99.99"));

    Assert.That(c.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("123.40"));

    Assert.That(d.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("10101.10"));

    // In this particular implementation, values that can't be expressed in
    // two decimal places are unaltered, so this remains as-is.
    Assert.That(e.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("908.7650"));
}

7

Anda dapat menggunakan system.globalisasi untuk memformat angka dalam format apa pun yang diperlukan.

Sebagai contoh:

system.globalization.cultureinfo ci = new system.globalization.cultureinfo("en-ca");

Jika Anda memiliki decimal d = 1.2300000dan Anda perlu memotongnya ke 2 tempat desimal maka dapat dicetak seperti ini di d.Tostring("F2",ci);mana F2 adalah string yang membentuk ke 2 tempat desimal dan ci adalah locale atau cultureinfo.

untuk info lebih lanjut, periksa tautan ini
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx


+1 tetapi - objek CultureInfo hanya akan memengaruhi karakter unicode yang digunakan untuk menunjukkan tempat desimal. misalnya. fr-FR akan menggunakan koma bukan tanda titik. Ini tidak terkait dengan jumlah tempat desimal yang diberikan.
MattDavey

4

https://msdn.microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx

Tautan ini menjelaskan secara terperinci bagaimana Anda dapat menangani masalah Anda dan apa yang dapat Anda lakukan jika Anda ingin mempelajari lebih lanjut. Untuk tujuan kesederhanaan, apa yang ingin Anda lakukan adalah

double whateverYouWantToChange = whateverYouWantToChange.ToString("F2");

jika Anda menginginkan ini untuk mata uang, Anda dapat membuatnya lebih mudah dengan mengetikkan "C2" daripada "F2"


1
Double Amount = 0;
string amount;
amount=string.Format("{0:F2}", Decimal.Parse(Amount.ToString()));

1

Jika Anda hanya perlu menyimpan 2 tempat desimal (mis. Potong semua angka desimal lainnya):

decimal val = 3.14789m;
decimal result = Math.Floor(val * 100) / 100; // result = 3.14

Jika Anda hanya perlu menyimpan 3 tempat desimal:

decimal val = 3.14789m;
decimal result = Math.Floor(val * 1000) / 1000; // result = 3.147
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.