Làm cách nào để làm tròn một giá trị thập phân đến 2 vị trí thập phân (cho đầu ra trên một trang)


649

Khi hiển thị giá trị của số thập phân hiện tại .ToString(), chính xác là thích 15 vị trí thập phân và vì tôi đang sử dụng nó để biểu thị đô la và xu, tôi chỉ muốn đầu ra là 2 chữ số thập phân.

Tôi có sử dụng một biến thể .ToString()cho việc này không?

Câu trả lời:


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

hoặc là

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

31
vấn đề ở đây là khi chúng ta có 0,00; nó trả về một chuỗi rỗng
Jronny

164
Sau đó, bạn có thể thực hiện binaryVar.ToString ("0. ##"). Bạn cũng có thể sử dụng 0,00 làm chuỗi định dạng.
albertein

54
Với giải pháp này, bạn sẽ không có định dạng văn hóa mà người ta mong đợi khi đọc số. Đối với điều này, bạn nên sử dụng ToString ("N2") hoặc ToString ("N").
Shautieh

2
@Hill DecimalDoublekiểu ToStringphương thức chấp nhận đối số để định dạng. Trước tiên hãy thử chuyển đổi giá trị của bạn thành Số thập phân / Đôi.
sohaiby

1
@ f470071 Số thập phân là loại giá trị và do đó không bao giờ được "sửa đổi". Bất kể, ToString () chưa bao giờ được dự kiến ​​sẽ sửa đổi nội dung của bất cứ thứ gì nó được gọi.
Justin Skiles

590

Tôi biết đây là một câu hỏi cũ, nhưng tôi đã ngạc nhiên khi thấy rằng dường như không ai đăng một câu trả lời đó;

  1. Không sử dụng làm tròn ngân hàng
  2. Không giữ giá trị dưới dạng thập phân.

Đây là những gì tôi sẽ sử dụng:

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

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


3
ToString hoặc chuỗi.Format không sử dụng làm tròn ngân hàng: msdn.microsoft.com/en-us/l Library / 0c899ak8.aspx
sectionToggle1

1
@MatthijsWessels Tôi biết ... nhưng nó cũng không giữ giá trị dưới dạng thập phân.
Mike M.

1
Đây là một cách tốt hơn để thực sự đại diện cho hai vị trí thập phân vì nó sẽ không thả các số 0 ở cuối.
LiquidDrummer

355
decimalVar.ToString("F");

Điều này sẽ:

  • Làm tròn đến 2 chữ số thập phân, vd. 23.45623.46
  • Đảm bảo rằng luôn có 2 chữ số thập phân, vd. 2323.00; 12.512.50

Lý tưởng để hiển thị tiền tệ.

Kiểm tra tài liệu trên ToString ("F") (cảm ơn Jon Schneider).


10
Điều này hoạt động tốt khi chỉ có 1 thập phân; .ToString ("#. ##") không thành công. Câu trả lời này tốt hơn nhiều
Eric Frick

2
Nó sẽ không làm tròn 23.456 => 23.46?
rtpHarry

14
Tài liệu về ý nghĩa của chữ "F" ở đây và cách thức hoạt động của nó: msdn.microsoft.com/en-us/l Library / trộm
Jon Schneider

4
Tại sao không .ToString ("N") thay vì "F"? Theo hiểu biết của tôi, cả hai sẽ làm việc cho nhu cầu của câu hỏi này, nhưng N cũng sẽ đặt dấu phẩy cho hàng ngàn.
jgerman

Lưu ý: Có .thể được thay thế bằng ,dựa trên văn hóa. Bạn nên chuyển qua CultureInfo.InvariantCulturelàm đối số thứ hai để vô hiệu hóa điều này.
Duncan Luk

106

Nếu bạn chỉ cần điều này để hiển thị, hãy sử dụng chuỗi.Format

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

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

"M" là hậu tố thập phân. Về hậu tố thập phân:

http://msdn.microsoft.com/en-us/l Library / 430x0z75.aspx


10
Về mặt kỹ thuật, đối với một số thập phân, nó sẽ là 123,4567m, đúng không? Không có hậu tố "m", nó là một đôi
Adam Tegen

2
hoặc phím tắt $ "{value: 0,00}"
mamczas

56

Cho số thập phân d = 12.345; các biểu thức d.ToString ("C") hoặc String.Format ("{0: C}", d) mang lại $ 12,35 - lưu ý rằng cài đặt tiền tệ của văn hóa hiện tại bao gồm cả biểu tượng được sử dụng.

Lưu ý rằng "C" sử dụng số chữ số từ văn hóa hiện tại. Bạn luôn có thể ghi đè mặc định để buộc độ chính xác cần thiết với C{Precision specifier}like String.Format("{0:C2}", 5.123d).


4
@ Slick86 - dấu hiệu hiện tại
fubo

48

Nếu bạn muốn nó được định dạng bằng dấu phẩy cũng như dấu thập phân (nhưng không có ký hiệu tiền tệ), chẳng hạn như 3,456,789.12 ...

decimalVar.ToString("n2");

1
Câu trả lời tốt hơn vì câu hỏi là về việc xuất ra trên một trang và định dạng số rất quan trọng đối với số lớn. Ngoài ra, "n *" có tính đến văn hóa hiện tại, vì vậy nó có thể là "3.456.789,12", "3 456 789,12", v.v.
Shautieh

29

Đã có hai câu trả lời cho điểm cao liên quan đến Decimal.Round (...) nhưng tôi nghĩ cần thêm một chút giải thích - bởi vì có một tính chất quan trọng bất ngờ của Decimal không rõ ràng.

Một số thập phân 'biết' có bao nhiêu vị trí thập phân dựa trên nơi nó đến.

Ví dụ, những điều sau đây có thể gây bất ngờ:

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"

Thực hiện các thao tác tương tự với Doublesẽ không có vị trí thập phân ( "25") cho mỗi mục trên.

Khi bạn muốn một số thập phân đến 2 chữ số thập phân có khoảng 95% cơ hội bởi vì đó là loại tiền tệ trong trường hợp này có thể tốt trong 95% thời gian:

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

Hoặc trong XAML bạn chỉ cần sử dụng {Binding Price, StringFormat=c}

Một trường hợp tôi gặp phải khi tôi cần một số thập phân AS một số thập phân là khi gửi XML đến dịch vụ web của Amazon. Dịch vụ đã phàn nàn vì giá trị thập phân (ban đầu từ SQL Server) đã được gửi 25.1200và bị từ chối, ( 25.12là định dạng dự kiến).

Tất cả những gì tôi cần làm là Decimal.Round(...)với 2 chữ số thập phân để khắc phục sự cố.

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

TypedValuelà loại Decimalvì vậy tôi không thể làm ToString("N2")và cần làm tròn nó và giữ nó như một decimal.


5
+1 đây là một câu trả lời tuyệt vời. Khi bạn nói rằng System.Decimal "biết có bao nhiêu vị trí thập phân" - thuật ngữ là System.Decimal không tự chuẩn hóa như các loại dấu phẩy động khác. Một thuộc tính hữu ích khác của System.Decimal là kết quả của các phép toán luôn có số vị trí thập phân cao nhất từ ​​các đối số đầu vào tức là. 1,0m + 2.000m = 3.000m . Bạn có thể sử dụng thực tế này để buộc một số thập phân không có vị trí thập phân đến 2 vị trí thập phân chỉ bằng cách nhân nó với 1,00m, ví dụ. 10m * 1,00m = 10,00m .
MattDavey

2
MattDavey không chính xác, độ chính xác thập phân được thêm vào. (1.0m * 1.00m) .ToString () = "1.000"
Kaido

2
Rất, rất hữu ích khi biết rằng "Một số thập phân 'biết' có bao nhiêu vị trí thập phân dựa trên nơi nó đến." Cảm ơn rất nhiều!
i lovcsharp

21

Đây là một chương trình Linqpad nhỏ để hiển thị các định dạng khác nhau:

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

Đây là kết quả:

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

Rất hiếm khi bạn muốn có một chuỗi rỗng nếu giá trị bằng 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"

Câu trả lời được xếp hạng hàng đầu là không chính xác và đã lãng phí 10 phút (hầu hết) thời gian của mọi người.


1
về cơ bản "#"có nghĩa là chữ số của số (nếu cần) (không cần đệm nếu không cần) "0"có nghĩa là chữ số (không có gì) (được đệm bằng số không nếu không có sẵn)
Mr Heelis

10

Câu trả lời của Mike M. là hoàn hảo đối với tôi trên .NET, nhưng .NET Core không có decimal.Roundphương pháp tại thời điểm viết.

Trong .NET Core, tôi đã phải sử dụng:

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

Một phương pháp hacky, bao gồm chuyển đổi thành chuỗi, là:

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

Không ai trong số này làm chính xác những gì tôi cần, để buộc 2 dp và làm tròn thành0.005 -> 0.01

Buộc 2 dp yêu cầu tăng độ chính xác thêm 2 dp để đảm bảo chúng tôi có ít nhất 2 dp

sau đó làm tròn để đảm bảo chúng tôi không có nhiều hơn 2 dp

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

6.665m.ToString() -> "6.67"

6.6m.ToString() -> "6.60"

9

Câu trả lời được xếp hạng cao nhất mô tả một phương pháp để định dạng biểu diễn chuỗi của giá trị thập phân và nó hoạt động.

Tuy nhiên, nếu bạn thực sự muốn thay đổi độ chính xác được lưu thành giá trị thực, bạn cần phải viết một cái gì đó như sau:

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

Một bài kiểm tra đơn vị ví dụ:

[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

Bạn có thể sử dụng system.globalization để định dạng một số theo bất kỳ định dạng bắt buộc nào.

Ví dụ:

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

Nếu bạn có một decimal d = 1.2300000và bạn cần cắt nó thành 2 chữ số thập phân thì nó có thể được in như thế này trong d.Tostring("F2",ci);đó F2 là chuỗi tạo thành 2 chữ số thập phân và ci là miền địa phương hoặc văn hóa.

để biết thêm thông tin, hãy kiểm tra liên kết này
http://msdn.microsoft.com/en-us/l Library / dawawy9k.aspx


+1 nhưng - đối tượng CultureInfo sẽ chỉ ảnh hưởng đến ký tự unicode được sử dụng để biểu thị vị trí thập phân. ví dụ. fr-FR sẽ sử dụng dấu phẩy thay vì dấu chấm. Nó không liên quan đến số lượng vị trí thập phân được hiển thị.
MattDavey

4

https://msdn.microsoft.com/en-us/l Library / dawawy9k% 28v = vs.110% 29.aspx

Liên kết này giải thích chi tiết về cách bạn có thể xử lý vấn đề của mình và những gì bạn có thể làm nếu muốn tìm hiểu thêm. Đối với mục đích đơn giản, những gì bạn muốn làm là

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

nếu bạn muốn loại tiền này, bạn có thể làm cho nó dễ dàng hơn bằng cách nhập "C2" thay vì "F2"


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

1

Nếu bạn chỉ cần giữ 2 chữ số thập phân (nghĩa là cắt bỏ tất cả phần còn lại của chữ số thập phân):

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

Nếu bạn chỉ cần giữ 3 chữ số thập phân:

decimal val = 3.14789m;
decimal result = Math.Floor(val * 1000) / 1000; // result = 3.147
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.