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?

wow
sumber

Jawaban:

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

atau

decimalVar.ToString ("0.##"); // returns "0"  when decimalVar == 0
albertein
sumber
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

Mike M.
sumber
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).

Sofox
sumber
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).

Hafthor
sumber
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");
Joel Mueller
sumber
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.

Simon_Weaver
sumber
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
===================
Apa yang Akan Menjadi Keren
sumber
16

Math.Round Method (Desimal, Int32)

John Smith
sumber
bukankah itu menggunakan pembulatan bankir?
Danimal
Ini adalah cara terbaik, karena nilainya tidak dikonversi ke string dan Anda masih dapat melakukan operasi matematika
shinji14
@Danimal: Anda dapat memberikan argumen ketiga untuk mengubah tipe pembulatan
Jay Sullivan
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.

goamn
sumber
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);
}
Hoki
sumber
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"
Kaido
sumber
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"));
}
Alex
sumber
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

Smitha Poluri
sumber
+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"

Jeff Jose
sumber
1
Double Amount = 0;
string amount;
amount=string.Format("{0:F2}", Decimal.Parse(Amount.ToString()));
JIYAUL MUSTAPHA
sumber
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
Aleksei Mialkin
sumber