ฉันจะปัดเศษทศนิยมเป็นทศนิยม 2 ตำแหน่ง (สำหรับผลลัพธ์บนหน้าเว็บ)


649

เมื่อแสดงค่าทศนิยมในขณะนี้ด้วย .ToString()ความแม่นยำเหมือนทศนิยม 15 ตำแหน่งและเนื่องจากฉันใช้เพื่อแทนดอลลาร์และเซ็นต์ฉันต้องการเฉพาะผลลัพธ์เป็นทศนิยม 2 ตำแหน่ง

ฉันใช้รูปแบบของ.ToString()สิ่งนี้หรือไม่?

คำตอบ:


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

หรือ

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

31
ปัญหาคือเมื่อเรามี 0.00; มันจะส่งกลับสตริงที่ว่างเปล่า
Jronny

164
จากนั้นคุณสามารถทำ decimalVar.ToString ("0. ##") คุณยังสามารถใช้ 0.00 เป็นสตริงการจัดรูปแบบ
albertein

54
ด้วยวิธีนี้คุณจะไม่มีวัฒนธรรมการจัดรูปแบบที่คาดหวังเมื่ออ่านตัวเลข สำหรับสิ่งนี้คุณควรใช้ ToString ("N2") หรือ ToString ("N")
Shautieh

2
@Hill DecimalและวิธีการDoubleพิมพ์ToStringยอมรับอาร์กิวเมนต์สำหรับการจัดรูปแบบ ลองแปลงค่าของคุณเป็น Decimal / Double ก่อน
sohaiby

1
@ f470071 Decimals เป็นประเภทค่าและไม่เคยมีการ "แก้ไข" โดยไม่คำนึงถึง ToString () ไม่เคยคาดหวังว่าจะแก้ไขเนื้อหาของสิ่งที่มันถูกเรียก
Justin Skiles

590

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ฉันประหลาดใจเมื่อเห็นว่าไม่มีใครดูเหมือนจะโพสต์คำตอบนั้น

  1. ไม่ได้ใช้การปัดเศษนายธนาคาร
  2. ไม่ได้เก็บค่าเป็นทศนิยม

นี่คือสิ่งที่ฉันจะใช้:

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

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


3
ToString หรือ string รูปแบบไม่ใช้การปัดเศษของธนาคาร: msdn.microsoft.com/en-us/library/0c899ak8.aspx#sectionToggle1
Matthijs Wessels

1
@ MatthijsWessels ฉันรู้ ... แต่มันก็ไม่ได้เก็บค่าเป็นทศนิยมเช่นกัน
Mike M.

1
นี่เป็นวิธีที่ดีกว่าในการแสดงทศนิยมสองตำแหน่งอย่างแท้จริงเนื่องจากจะไม่ทำให้ค่าศูนย์ต่อท้าย
LiquidDrummer

355
decimalVar.ToString("F");

นี่จะ:

  • ปัดเศษเป็นทศนิยม 2 ตำแหน่งเช่น 23.45623.46
  • ตรวจสอบให้แน่ใจว่ามีทศนิยม 2 ตำแหน่งเสมอเช่น 2323.00; 12.512.50

เหมาะสำหรับการแสดงสกุลเงิน

ตรวจสอบเอกสารเกี่ยวกับToString ("F") (ขอบคุณ Jon Schneider)


10
วิธีนี้ใช้งานได้ดีเมื่อมีทศนิยม 1 ตำแหน่งเท่านั้น .ToString ("#. ##") ล้มเหลว คำตอบนี้ดีกว่ามาก
Eric Frick

2
มันจะไม่รอบ 23.456 => 23.46?
rtpHarry

14
เอกสารเกี่ยวกับความหมายของ "F" ที่นี่และวิธีการทำงาน: msdn.microsoft.com/en-us/library/…
Jon Schneider

4
ทำไมไม่. ToString ("N") แทนที่จะเป็น "F" เป็นความเข้าใจของฉันที่พวกเขาจะทำงานเพื่อตอบสนองความต้องการของคำถามนี้ แต่ N จะใส่เครื่องหมายจุลภาคสำหรับตัวเลขเป็นหลักพัน
jgerman

หมายเหตุ: .อาจถูกแทนที่ด้วย,ตามวัฒนธรรม คุณควรผ่านไปCultureInfo.InvariantCultureเป็นอาร์กิวเมนต์ที่สองเพื่อปิดการใช้งานนี้
Duncan Luk

106

หากคุณต้องการสิ่งนี้สำหรับการแสดงผลใช้สตริงรูปแบบ

String.Format("{0:0.00}", 123.4567m);      // "123.46"

http://www.csharp-examples.net/string-format-double/

"m" เป็นคำต่อท้ายทศนิยม เกี่ยวกับคำต่อท้ายทศนิยม:

http://msdn.microsoft.com/en-us/library/364x0z75.aspx


10
ในทางเทคนิคสำหรับทศนิยมมันจะเป็น 123.4567m ใช่ไหม หากไม่มีคำต่อท้าย "m" มันจะเป็นสองเท่า
Adam Tegen

2
หรือทางลัด $ "{value: 0.00}"
mamczas

56

ได้รับทศนิยม d = 12.345; นิพจน์d.ToString ("C")หรือString.Format ("{0: C}", d)ให้ผลตอบแทน$ 12.35 - โปรดทราบว่าการใช้การตั้งค่าสกุลเงินของวัฒนธรรมปัจจุบันรวมถึงสัญลักษณ์นั้น

โปรดทราบว่า"C"ใช้จำนวนตัวเลขจากวัฒนธรรมปัจจุบัน คุณสามารถแทนที่ค่าเริ่มต้นที่จะบังคับให้มีความแม่นยำที่จำเป็นด้วยเช่นC{Precision specifier}String.Format("{0:C2}", 5.123d)


4
@ Slick86 - สัญญาณปัจจุบัน
fubo

48

หากคุณต้องการให้จัดรูปแบบด้วยเครื่องหมายจุลภาคเช่นเดียวกับจุดทศนิยม (แต่ไม่มีสัญลักษณ์สกุลเงิน) เช่น 3,456,789.12 ...

decimalVar.ToString("n2");

1
คำตอบที่ดีขึ้นเนื่องจากคำถามเกี่ยวกับผลลัพธ์บนหน้าและการจัดรูปแบบตัวเลขมีความสำคัญสำหรับคนจำนวนมาก นอกจากนี้ "n *" ยังคำนึงถึงวัฒนธรรมปัจจุบันดังนั้นจึงอาจเป็น "3.456.789,12", "3 456 789,12" ฯลฯ
Shautieh

29

มีคำตอบให้คะแนนสูงสองคำที่อ้างถึงเป็นทศนิยมรอบ (... ) แต่ฉันคิดว่าจำเป็นต้องมีคำอธิบายเพิ่มเติมอีกเล็กน้อย - เนื่องจากมีคุณสมบัติที่สำคัญที่ไม่คาดคิดของทศนิยมที่ไม่ชัดเจน

ทศนิยม 'รู้' ว่ามีทศนิยมกี่ตำแหน่งตามที่มาจาก

ตัวอย่างเช่นต่อไปนี้อาจไม่คาดคิด:

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"

การดำเนินการเดียวกันกับDoubleจะไม่มีตำแหน่งทศนิยม ( "25") สำหรับแต่ละข้อด้านบน

เมื่อคุณต้องการตำแหน่งทศนิยมเป็นทศนิยม 2 ตำแหน่งมีโอกาส 95% เนื่องจากสกุลเงินที่ใช้ในกรณีนี้อาจใช้ได้ถึง 95%:

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

หรือใน XAML คุณเพียงแค่ใช้ {Binding Price, StringFormat=c}

กรณีหนึ่งฉันวิ่งเข้าไปในที่ที่ฉันต้องการทศนิยมตามทศนิยมคือเมื่อส่ง XML ไปยังเว็บเซอร์ของ Amazon บริการบ่นเนื่องจากค่าทศนิยม (เดิมจาก SQL Server) ถูกส่งเป็น25.1200และปฏิเสธ (25.12เป็นรูปแบบที่คาดไว้)

สิ่งที่ฉันต้องทำคือDecimal.Round(...)มีทศนิยม 2 ตำแหน่งเพื่อแก้ไขปัญหา

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

TypedValueเป็นชนิดDecimalดังนั้นผมจึงไม่เพียงแค่ทำและจำเป็นต้องรอบมันและทำให้มันเป็นToString("N2")decimal


5
+1 นี่คือคำตอบที่ดี เมื่อคุณพูดว่า System.Decimal "รู้ว่ามีทศนิยมกี่ตำแหน่ง" - คำนี้คือ System.Decimal ไม่ได้ทำให้ตนเองเป็นปกติ (normalizing)เช่นเดียวกับประเภทจุดลอยอื่น ๆ คุณสมบัติที่มีประโยชน์อีกอย่างหนึ่งของ System.Decimal คือผลลัพธ์ของการดำเนินการทางคณิตศาสตร์มักจะมีจำนวนทศนิยมสูงสุดจากอาร์กิวเมนต์ที่ป้อนเข้าเช่น 1.0m + 2.000m = 3.000m คุณสามารถใช้ข้อเท็จจริงนี้เพื่อบังคับให้ทศนิยมโดยไม่มีทศนิยมให้เป็นทศนิยม 2 ตำแหน่งเพียงแค่คูณด้วย 1.00m เช่น 10m * 1.00m = 10.00m
MattDavey

2
MattDavey ไม่ถูกต้องเพิ่มความแม่นยำทศนิยม (1.0m * 1.00m) .ToString () = "1.000"
Kaido

2
มันมีประโยชน์มากที่จะรู้ว่า "ทศนิยม" รู้ "ว่ามีทศนิยมกี่ตำแหน่งตามที่มาจาก" ขอบคุณมาก!
iheartcsharp

21

นี่คือโปรแกรม Linqpad เล็ก ๆ น้อย ๆ ในการแสดงรูปแบบที่แตกต่างกัน:

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

นี่คือผลลัพธ์:

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
===================

16

ไม่ใช้การปัดเศษของนายธนาคารใช่ไหม
Danimal

นี่เป็นวิธีที่ดีที่สุดเพราะค่าไม่ได้แปลงเป็นสตริงและคุณยังสามารถทำการดำเนินการทางคณิตศาสตร์ได้
shinji14

@Danimal: คุณสามารถระบุอาร์กิวเมนต์ที่สามเพื่อเปลี่ยนประเภทการปัดเศษ
Jay Sullivan

11

คุณต้องการสตริงว่างเปล่าน้อยมากถ้าค่าเป็น 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"

คำตอบที่ได้รับคะแนนสูงสุดไม่ถูกต้องและเสียเวลา (ส่วนใหญ่) ไป 10 นาที


1
โดยทั่วไป "#"หมายถึงตัวเลขของตัวเลข (ถ้าจำเป็น) (โดยไม่ต้องใส่ในหากไม่จำเป็น) "0"หมายถึงตัวเลขของตัวเลข (ไม่มี mater อะไร) (มีค่าเป็นศูนย์ถ้าไม่มี)
Mr Heelis

10

คำตอบของ Mike M.นั้นสมบูรณ์แบบสำหรับฉันใน. NET แต่. NET Core ไม่มีdecimal.Roundวิธีในขณะที่เขียน

ใน. NET Core ฉันต้องใช้:

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

วิธีแฮ็กรวมถึงการแปลงเป็นสตริงคือ:

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

สิ่งเหล่านี้ไม่ได้ทำตามที่ฉันต้องการเพื่อบังคับให้2 dpและปัดเศษเป็น0.005 -> 0.01

การบังคับ 2 dp ต้องเพิ่มความแม่นยำ 2 dp เพื่อให้แน่ใจว่าเรามีอย่างน้อย 2 dp

จากนั้นปัดเศษเพื่อให้แน่ใจว่าเราไม่ได้มีมากกว่า 2 dp

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

6.665m.ToString() -> "6.67"

6.6m.ToString() -> "6.60"

9

คำตอบที่ติดอันดับสูงสุดอธิบายวิธีการจัดรูปแบบการแทนค่าสตริงของทศนิยมและใช้งานได้

อย่างไรก็ตามหากคุณต้องการเปลี่ยนความแม่นยำที่บันทึกเป็นค่าจริงคุณต้องเขียนสิ่งต่อไปนี้:

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

ตัวอย่างการทดสอบหน่วย:

[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

คุณสามารถใช้ system.globalization เพื่อจัดรูปแบบตัวเลขในรูปแบบที่ต้องการ

ตัวอย่างเช่น:

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

หากคุณมี a decimal d = 1.2300000และคุณต้องตัดให้เหลือทศนิยม 2 ตำแหน่งมันสามารถพิมพ์ได้เช่นนี้d.Tostring("F2",ci);โดยที่ F2 คือสตริงที่สร้างเป็นทศนิยม 2 ตำแหน่งและ ci คือ locale หรือ cultureinfo

สำหรับข้อมูลเพิ่มเติมตรวจสอบลิงค์นี้
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx


+1 แต่ - วัตถุ CultureInfo จะส่งผลต่ออักขระ Unicode ที่ใช้เพื่อแสดงตำแหน่งทศนิยมเท่านั้น เช่น. fr-FR จะใช้เครื่องหมายจุลภาคแทนจุด มันไม่เกี่ยวข้องกับจำนวนตำแหน่งทศนิยมที่แสดงผล
MattDavey

4

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

ลิงก์นี้จะอธิบายรายละเอียดเกี่ยวกับวิธีการจัดการปัญหาของคุณและสิ่งที่คุณสามารถทำได้หากคุณต้องการเรียนรู้เพิ่มเติม เพื่อจุดประสงค์ที่เรียบง่ายสิ่งที่คุณต้องการทำคือ

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

หากคุณต้องการสิ่งนี้สำหรับสกุลเงินคุณสามารถทำได้ง่ายขึ้นโดยพิมพ์ "C2" แทน "F2"



1

หากคุณต้องการเก็บทศนิยม 2 ตำแหน่งเท่านั้น (เช่นตัดส่วนที่เหลือของตัวเลขทศนิยมทั้งหมด):

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

หากคุณต้องการเก็บทศนิยม 3 ตำแหน่งไว้เท่านั้น:

decimal val = 3.14789m;
decimal result = Math.Floor(val * 1000) / 1000; // result = 3.147
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.