2010-03-16 204 views
112

Làm cách nào để định dạng Double thành String trong C# để chỉ có hai chữ số thập phân?Định dạng C# Double - ToString() với hai chữ số thập phân nhưng không làm tròn

Nếu tôi sử dụng String.Format("{0:0.00}%", myDoubleValue) thì số đó sẽ được làm tròn và tôi muốn cắt ngắn đơn giản mà không làm tròn. Tôi cũng muốn chuyển đổi thành String để trở nên nhạy cảm với văn hóa.

+0

Ý anh là gì bởi " văn hóa nhạy cảm "? Điều đó có nghĩa là kết quả của định dạng phải khác nhau tùy thuộc vào giá trị văn hóa do nhà lập trình cung cấp? Hay bạn muốn sử dụng bất kỳ nền văn hóa nào là mặc định cho chuỗi hiện tại? – CesarGon

Trả lời

152

tôi sử dụng như sau:

double x = Math.Truncate(myDoubleValue * 100)/100; 

Ví dụ:

Nếu số 50,947563 và bạn sử dụng những điều sau đây, sau đây sẽ xảy ra:

- Math.Truncate(50.947563 * 100)/100; 
- Math.Truncate(5094.7563)/100; 
- 5094/100 
- 50.94 

Và có câu trả lời của bạn bị cắt bớt, bây giờ để định dạng chuỗi, chỉ cần thực hiện như sau:

string s = string.Format("{0:N2}%", x); // No fear of rounding and takes the default number format 
+2

-1 Bạn có thể thực hiện định dạng nhạy cảm với văn hóa trong cùng một bước 'string.Format' định dạng chuỗi. Xem câu trả lời của tôi dưới đây. – CesarGon

+0

Chính xác: áp phích yêu cầu một giải pháp bao gồm định dạng nhạy cảm với văn hóa. Câu trả lời của bạn là hoàn toàn OK trong phần cắt ngắn, nhưng, như bạn cũng chỉ ra, "sự thay đổi văn hóa sẽ cần phải được thực hiện một cách riêng biệt". Bạn không chỉ định cách thực hiện, vì vậy tôi nghĩ câu trả lời của bạn chỉ trả lời một phần cho câu hỏi. – CesarGon

+2

Được rồi, không sao, tôi chỉ đơn giản là viết phụ lục. –

30

Tôi đề nghị bạn cắt đầu tiên, và sau đó định dạng:

double a = 123.4567; 
double aTruncated = Math.Truncate(a * 100)/100; 
CultureInfo ci = new CultureInfo("de-DE"); 
string s = string.Format(ci, "{0:0.00}%", aTruncated); 

Sử dụng hằng số 100 cho 2 chữ số cắt ngắn; sử dụng số 1 theo sau bởi nhiều số 0 dưới dạng chữ số sau dấu thập phân mà bạn muốn. Sử dụng tên văn hóa bạn cần điều chỉnh kết quả định dạng.

0

Bạn cũng có thể viết IFormatProvider của riêng mình, mặc dù tôi cho rằng cuối cùng bạn sẽ phải nghĩ ra một cách để thực hiện cắt ngắn thực tế.

.NET Framework cũng hỗ trợ định dạng tùy chỉnh. Điều này thường bao gồm việc tạo ra một lớp định dạng thực hiện cả IFormatProvider và ICustomFormatter. (msdn)

Ít nhất nó sẽ dễ dàng tái sử dụng được.

Có một bài viết về cách triển khai IFormatProvider/ICustomFormatter của riêng bạn here at CodeProject. Trong trường hợp này, "mở rộng" một định dạng số hiện có có thể là đặt cược tốt nhất. Nó không quá khó.

5

này đang làm việc cho tôi

string prouctPrice = Convert.ToDecimal(String.Format("{0:0.00}", Convert.ToDecimal(yourString))).ToString(); 
5

Các C# chức năng, như thể hiện bởi Kyle Rozendo:

string DecimalPlaceNoRounding(double d, int decimalPlaces = 2) 
{ 
    d = d * Math.Pow(10, decimalPlaces); 
    d = Math.Truncate(d); 
    d = d/Math.Pow(10, decimalPlaces); 
    return string.Format("{0:N" + Math.Abs(decimalPlaces) + "}", d); 
} 
64
decimal d = 0.241534545765m; 
decimal d2 = 0.241m; 
decimal d3 = 0.2m; 

d.ToString("0.##%");  //24.15% 
d2.ToString("0.##%");  //24.1% 
d3.ToString("0.##%");  //20% 

http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/

+7

Điều này không hoạt động. Hãy thử nó với 0.2415999. Giải pháp này làm tròn, không cắt ngắn. – BJury

+2

Chà, có rất nhiều phiếu bầu và nó đang sử dụng làm tròn. Nó có thể là cần thiết để chỉ ra rằng làm tròn đang hướng tới vị trí thập phân gần nhất được yêu cầu, trong khi cắt ngắn được cắt ra sau khi số thập phân gần nhất yêu cầu. – mysticcoder

+0

@mysticcoder Tôi đoán câu trả lời của tôi nhận được rất nhiều upvotes bởi vì họ đến câu hỏi ops trong một tìm kiếm của Google theo cùng một cách tôi đã làm, tìm cách loại bỏ dấu 0, và không tìm kiếm mong muốn làm tròn của câu hỏi ops. Tôi đoán tôi nên xóa câu trả lời của mình ... –

2

Tôi biết đây là một chủ đề cũ nhưng tôi đã phải làm điều này. Trong khi các phương pháp tiếp cận khác ở đây hoạt động, tôi muốn một cách dễ dàng để có thể ảnh hưởng đến nhiều cuộc gọi đến string.format. Vì vậy, việc thêm Math.Truncate vào tất cả các cuộc gọi không thực sự là một lựa chọn tốt. Cũng như một số định dạng được lưu trữ trong cơ sở dữ liệu, nó thậm chí còn tồi tệ hơn.

Vì vậy, tôi đã cung cấp tùy chỉnh định dạng mà sẽ cho phép tôi để thêm cắt ngắn vào chuỗi định dạng, ví dụ:

string.format(new FormatProvider(), "{0:T}", 1.1299); // 1.12 
string.format(new FormatProvider(), "{0:T(3)", 1.12399); // 1.123 
string.format(new FormatProvider(), "{0:T(1)0,000.0", 1000.9999); // 1,000.9 

Việc thực hiện khá đơn giản và có thể dễ dàng thể mở rộng đến các yêu cầu khác.

public class FormatProvider : IFormatProvider, ICustomFormatter 
{ 
    public object GetFormat(Type formatType) 
    { 
     if (formatType == typeof (ICustomFormatter)) 
     { 
      return this; 
     } 
     return null; 
    } 

    public string Format(string format, object arg, IFormatProvider formatProvider) 
    { 
     if (arg == null || arg.GetType() != typeof (double)) 
     { 
      try 
      { 
       return HandleOtherFormats(format, arg); 
      } 
      catch (FormatException e) 
      { 
       throw new FormatException(string.Format("The format of '{0}' is invalid.", format)); 
      } 
     } 

     if (format.StartsWith("T")) 
     { 
      int dp = 2; 
      int idx = 1; 
      if (format.Length > 1) 
      { 
       if (format[1] == '(') 
       { 
        int closeIdx = format.IndexOf(')'); 
        if (closeIdx > 0) 
        { 
         if (int.TryParse(format.Substring(2, closeIdx - 2), out dp)) 
         { 
          idx = closeIdx + 1; 
         } 
        } 
        else 
        { 
         throw new FormatException(string.Format("The format of '{0}' is invalid.", format)); 
        } 
       } 
      } 
      double mult = Math.Pow(10, dp); 
      arg = Math.Truncate((double)arg * mult)/mult; 
      format = format.Substring(idx); 
     } 

     try 
     { 
      return HandleOtherFormats(format, arg); 
     } 
     catch (FormatException e) 
     { 
      throw new FormatException(string.Format("The format of '{0}' is invalid.", format)); 
     } 
    } 

    private string HandleOtherFormats(string format, object arg) 
    { 
     if (arg is IFormattable) 
     { 
      return ((IFormattable) arg).ToString(format, CultureInfo.CurrentCulture); 
     } 
     return arg != null ? arg.ToString() : String.Empty; 
    } 
} 
7

tôi sử dụng price.ToString("0.00") để nhận được hàng đầu 0s

10

phương pháp đơn giản, sử dụng định dạng chuỗi số:

double total = "43.257" 
MessageBox.Show(total.ToString("F")); 
+1

Trên thực tế phương pháp này làm tròn https://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx#FFormatString – elvin

1

sau đây có thể được sử dụng để chỉ hiển thị trong đó sử dụng tài sản của Chuỗi ..

double value = 123.456789; 
String.Format("{0:0.00}", value); 
3

Cách thêm một decima phụ l mà là để được làm tròn và sau đó bỏ đi:

var d = 0.241534545765; 
var result1 = d.ToString("0.###%"); 

var result2 = result1.Remove(result1.Length - 1); 
+1

Thật buồn cười như thế nào một câu trả lời không làm việc có 60 phiếu bầu (như của ngày hôm nay), và giải pháp khá đơn giản và chống đạn này chỉ có một ... –

+0

Điều này sẽ không hoạt động trong trường hợp làm tròn ảnh hưởng nhiều hơn một chữ số phía trên ngưỡng cắt. Ví dụ: 0.199999 sẽ kết thúc bằng 0,20 với mã này, thay vì 0,19. – Bernem

0

Để những gì là giá trị, cho thấy tiền tệ, bạn có thể sử dụng "C":

double cost = 1.99; 
m_CostText.text = cost.ToString("C"); /*C: format as currentcy */ 

Output: $1.99

Các vấn đề liên quan