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.45623.46
  • Her zaman 2 ondalık basamak bulunduğundan emin olun, örn. 2323.00; 12.512.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.