Ondalık bir değeri nasıl 2 ondalık basamağa yuvarlayabilirim (sayfadaki çıktı için)


649

Şu anda ondalık basamak değerini görüntülerken, .ToString()15 ondalık basamaktan hoşlanmak doğrudur ve bunu dolar ve sentleri temsil etmek için kullandığımdan, çıktının yalnızca 2 ondalık basamak olmasını istiyorum.

Bunun için bir varyasyon kullanabilir miyim .ToString()?

Yanıtlar:


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

veya

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

31
buradaki problem 0.00 olduğunda; boş bir dize döndürür.
— Jronny

164
Sonra decimalVar.ToString ("0. ##") yapabilirsiniz. Biçimlendirme dizesi olarak 0,00 kullanabilirsiniz.
— albertein

54
Bu çözümle, sayıları okurken bekleyebileceğiniz kültür biçimlendirmesine sahip olmayacaksınız. Bunun için ToString ("N2") veya ToString ("N") kullanmalısınız.
— Shautieh

2
@Hill Decimaland Doubletype ToStringyöntemi, biçimlendirme için bağımsız değişkeni kabul eder. Önce değerinizi Ondalık / Çift'e dönüştürmeyi deneyin.
— sohaiby

1
@ f470071 Ondalık değerler tiptir ve bu nedenle asla "değiştirilmez". Ne olursa olsun, ToString () 'in çağrıldığı her şeyin içeriğini değiştirmesi beklenmemiştir.
— Justin Skiles

590

Bunun eski bir soru olduğunu biliyorum, ama kimsenin böyle bir cevap göndermediğini görünce şaşırdım;

  1. Bankacıları yuvarlama kullanmadı
  2. Değeri ondalık sayı olarak tutmadı.

Ben ne kullanacağım:

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

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


3
ToString veya string.Format yuvarlanan bankacılar kullanmaz: msdn.microsoft.com/en-us/library/0c899ak8.aspx#sectionToggle1
— Matthijs Wessels 21:13

1
@MatthijsWessels biliyorum ... ama değeri ondalık sayı olarak da tutmuyor.
— Mike

1
Bu, sondaki sıfırları bırakmayacağı için iki ondalık basamağı gerçekten temsil etmenin daha iyi bir yoludur.
— LiquidDrummer

355
decimalVar.ToString("F");

Bu irade:

  • 2 ondalık basamağa yuvarlayın örn. 23.456→23.46
  • Her zaman 2 ondalık basamak bulunduğundan emin olun, örn. 23→ 23.00; 12.5→12.50

Para birimini görüntülemek için idealdir.

ToString ("F") ile ilgili belgelere göz atın (Jon Schneider sayesinde).


10
Bu yalnızca 1 ondalık olduğunda işe yarar; .ToString ("#. ##") başarısız. Bu cevap çok daha iyi
— Eric Frick

2
23.456 => 23.46'yı yuvarlamaz mı?
— rtpHarry

14
"F" nin burada ne anlama geldiğine ve nasıl çalıştığına dair belgeler: msdn.microsoft.com/en-us/library/…
— Jon Schneider

4
Neden "F" yerine .ToString ("N")? Bu soruların her ikisi de bu sorunun ihtiyaçları için çalışacaklarını düşünüyorum, ancak N binlerce kişide rakamlar için virgül koyacaktır.
— jgerman

Not: Kültüre göre .değiştirilebilir ,. Bunu CultureInfo.InvariantCulturedevre dışı bırakmak için ikinci argüman olarak geçmelisiniz .
— Duncan Luk


56

Verilen ondalık D = 12.345; ifadeleri ( "C") d.ToString veya String.format ( "{0: C}", d) elde $ 12.35 - sembolü dahil olmak üzere geçerli kültürün para birimi ayarları kullanıldığını not.

"C" nin mevcut kültürden basamak sayısı kullandığını unutmayın . C{Precision specifier}Benzer hassasiyeti zorunlu kılmak için her zaman varsayılanı geçersiz kılabilirsiniz String.Format("{0:C2}", 5.123d).


4
@ Slick86 - Şu anki işaret
— Fubo

48

3.456.789.12 gibi virgülle ve ondalık basamakla (ancak para birimi simgesi olmadan) biçimlendirilmesini istiyorsanız ...

decimalVar.ToString("n2");

1
Soru bir sayfada çıktı almakla ilgili daha iyi bir yanıt ve sayı biçimlendirmesi büyük sayılar için önemlidir. Ayrıca, "n *" mevcut kültürü dikkate alır, bu yüzden "3.456.789,12", "3 456 789,12", vb.
— Olabilir

29

Decimal.Round (...) 'a atıfta bulunan iki yüksek puanlama cevabı zaten var ama sanırım biraz daha fazla açıklama gerekli - çünkü Decimal'in beklenmedik önemli bir özelliği var.

Bir ondalık, nereden geldiğine bağlı olarak kaç ondalık basamak bulunduğunu bilir.

Örneğin, aşağıdakiler beklenmedik olabilir:

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"

Aynı işlemleri yapmak, yukarıdakilerin her biri için Doubleondalık basamak ( "25") vermez .

Ondalık basamaktan 2 ondalık basamağa kadar istediğinizde bunun yaklaşık% 95'lik bir şansı vardır, çünkü bu para birimidir, bu durumda bu muhtemelen% 95 oranında iyidir:

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

Veya XAML'de {Binding Price, StringFormat=c}

Ondalık AS olarak ondalık sayıya ihtiyaç duyduğum bir durum Amazon'un web servisine XML gönderirken oldu. Hizmet, ondalık bir değer (başlangıçta SQL Server'dan) olarak gönderildiği 25.1200ve reddedildiği için ( 25.12beklenen biçimdi) şikayet ediyordu.

Tek yapmam gereken Decimal.Round(...)sorunu çözmek için 2 ondalık basamağa sahipti.

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

TypedValuetiptedir DecimalSadece yapamadık bu yüzden ToString("N2")ve o yuvarlak ve olarak tutmak için gerekli decimal.


5
+1 bu harika bir cevap. System.Decimal "kaç ondalık basamak olduğunu biliyor" dediğinde - terim, System.Decimal diğer kayan nokta türleri gibi kendini normalleştirmiyor olmasıdır . System.Decimal'ın bir başka yararlı özelliği, matematik işlemlerinin sonucunun her zaman girdi bağımsız değişkenlerinden yani en fazla ondalık basamağa sahip olmasıdır. 1.0m + 2.000m = 3.000m . Bu gerçeği, ondalık basamak içermeyen bir ondalığı zorlamak için, yalnızca 1,00 m ile çarparak 2 ondalık basamağa zorlayabilirsiniz. 10m * 1.00m = 10.00m .
— MattDavey

2
MattDavey yanlış, ondalık duyarlık eklenir. (1.0m * 1.00m) .ToString () = "1.000"
— Kaido

2
"Bir ondalık basamakın, nereden geldiğine bağlı olarak kaç ondalık basamak bulunduğunu" bildiğini bilmek çok, çok yararlıdır. Çok teşekkürler!
— iheartcsharp

21

İşte farklı formatları gösteren küçük bir Linqpad programı:

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("===================");
}

Sonuçlar burada:

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

Değer 0 ise çok nadiren boş bir dize istersiniz.

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"

En yüksek puan alan cevap yanlış ve 10 dakikalık (çoğu) insanın zamanını boşa harcadı.


1
temel "#"olarak sayının rakamı (gerekirse) (eğer gerekli değilse dolgu olmadan) "0", rakamın rakamı (materyal yok) (mevcut değilse sıfırlarla doldurulmuş ) anlamına gelir
— Bay Heelis

10

Mike M.'nin cevabı .NET'te benim için mükemmeldi, ancak .NET Core'dadecimal.Round yazma sırasında yöntemi .

.NET Core'da şunları kullanmak zorunda kaldım:

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

Dizeye dönüştürme de dahil olmak üzere, hacky bir yöntem:

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

Bunların hiçbiri 2 dp'yi zorlamak için tam olarak ihtiyacım olanı yapmadı ve yuvarlamak için0.005 -> 0.01

En az 2 dp olmasını sağlamak için 2 dp zorlama hassasiyeti 2 dp arttırmayı gerektirir.

daha sonra 2 dp'den fazla olmadığımızdan emin olmak için yuvarlama

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

6.665m.ToString() -> "6.67"

6.6m.ToString() -> "6.60"

9

En yüksek puanlı yanıt , ondalık değerin dize temsilini biçimlendirmek için bir yöntemi açıklar ve çalışır.

Ancak, gerçek değere kaydedilen kesinliği gerçekten değiştirmek istiyorsanız, aşağıdaki gibi bir şey yazmanız gerekir:

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

Örnek bir birim testi:

[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

Bir sayıyı istenen biçimde biçimlendirmek için system.globalization komutunu kullanabilirsiniz.

Örneğin:

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

A'ya sahipseniz decimal d = 1.2300000ve 2 ondalık basamağa d.Tostring("F2",ci);kesmeniz gerekiyorsa, F2'nin 2 ondalık basamağa dizgi oluşturduğu ve ci yerel ya da cultureinfo olduğu şekilde yazdırılabilir .

daha fazla bilgi için bu bağlantıyı kontrol edin
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx


+1 ancak - CultureInfo nesnesi yalnızca ondalık yeri belirtmek için kullanılan unicode karakterini etkiler. Örneğin. fr-FR nokta yerine virgül kullanır. Oluşturulan ondalık basamak sayısı ile ilgili değildir.
— MattDavey

4

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

Bu bağlantı, sorununuzu nasıl ele alabileceğinizi ve daha fazla bilgi edinmek isterseniz neler yapabileceğinizi ayrıntılı olarak açıklar. Basitlik amacıyla, yapmak istediğiniz şey

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

bunu bir para birimi için istiyorsanız, "F2" yerine "C2" yazarak bunu kolaylaştırabilirsiniz


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

1

Yalnızca 2 ondalık basamak tutmanız gerekiyorsa (yani, diğer ondalık basamakları kesin):

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

Yalnızca 3 ondalık basamak tutmanız gerekiyorsa:

decimal val = 3.14789m;
decimal result = Math.Floor(val * 1000) / 1000; // result = 3.147
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.