2013-05-15 33 views
14

Tôi đang gặp sự cố khi tôi cố gắng chuyển đổi decimal? thành string. Kịch bản làSự cố chuyển đổi Thập phân ToString() trong C#

decimal decimalValue = .1211; 
string value = (decimalValue * 100).ToString(); 

Kết quả hiện tại: value = 12,1100

Dự kiến ​​kết quả: value = 12,11

Xin vui lòng cho tôi biết, những gì có thể lý do cho việc này.

+1

Lý do có thể là định dạng số mặc định của hệ thống cho số thập phân. –

+2

Bạn có muốn hiển thị nhiều hơn hai chữ số thập phân nếu chúng không khác không? Tức là, nếu bạn có '.12113405' bạn muốn nó xuất hiện dưới dạng' 12.113405'? –

+0

Chỉ là những gì tôi đã suy nghĩ: là nó chỉ là dấu chân sau, hoặc bạn muốn luôn luôn giới hạn bởi 2 số thập phân? Trong trường hợp trước đây, không có câu trả lời nào cung cấp câu trả lời hay. –

Trả lời

16

Decimal bảo bất kỳ zero dấu trong một số Decimal.Nếu bạn muốn hai chữ số thập phân thay vì:

decimal? decimalValue = .1211m; 
string value = ((decimal)(decimalValue * 100)).ToString("#.##") 

http://msdn.microsoft.com/en-us/library/0c899ak8.aspx

hoặc

string value = ((decimal)(decimalValue * 100)).ToString("N2") 

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

Từ System.Decimal:

Một deci số mal là một dấu chấm động giá trị bao gồm một dấu hiệu, một giá trị số trong đó mỗi chữ số trong giá trị dao động từ 0 đến 9, và một rộng yếu tố cho biết vị trí của một điểm thập phân nổi tách phân tách và các phần phân đoạn của giá trị số.

Các biểu diễn nhị phân của một giá trị thập phân bao gồm một dấu 1-bit, 96-bit số số nguyên, và mở rộng quy mô yếu tố dùng để chia 96-bit số nguyên và xác định những phần của nó là một phần thập phân. Các nhân rộng yếu tố là ngầm số 10, nâng lên một số mũ khác nhau, từ 0 đến 28. Do đó, nhị phân đại diện của một giá trị thập phân là dạng, ((-2 -2 )/10 (0 đến 28)), nơi -2 -1 bằng MINVALUE, và 2 -1 bằng maxvalue.

Hệ số chia tỷ lệ cũng giữ bất kỳ sốsố 0 trong số thập phân. Các con số 0 khi di chuyển không ảnh hưởng đến giá trị của một số thập phân trong các phép tính số học hoặc so sánh. Tuy nhiên, >> dấu 0 có thể là được hiển thị theo phương thức ToString nếu một chuỗi định dạng thích hợp được áp dụng < <.

Ghi chú:

  1. các nhân thập phân cần được đúc để thập phân, vì Nullable<decimal>.ToString không có nhà cung cấp định dạng
  2. như Chris chỉ ra bạn cần để xử lý các trường hợp đó, Nullable<decimal>null.Một cách là sử dụng Null-Coalescing-Operator:

    ((decimal)(decimalValue ?? 0 * 100)).ToString("N2") 
    

Bài viết này từ Jon Skeet rất đáng đọc:

Decimal floating point in .NET (Kết cho giữ số không nếu bạn thiếu kiên nhẫn)

+0

Truyền đến 'thập phân' sẽ ném một' InvalidOperationException' với mã này, trong khi mã ban đầu của Pushkar sẽ dẫn đến một chuỗi rỗng. Có thể không có liên quan trong trường hợp này mặc dù. –

+0

Xin lỗi Tim, tôi có nghĩa là nó sẽ ném khi 'decimalValue' là' null'. –

+0

@ChrisSinclair: Cảm ơn, đã thêm một nhận xét. –

6

Vì bạn đang sử dụng Nullable<T> làm phương pháp decimal, Nullable<T>.ToString() không có quá tải sẽ nhận các tham số mà bạn có thể sử dụng để định dạng.

Thay vì, bạn có thể truyền một cách rõ ràng đến decimal và bạn có thể sử dụng phương thức .ToString() để định dạng.

Chỉ cần sử dụng định dạng "0.00" trong phương thức .ToString() của bạn.

decimal? decimalValue = .1211M; 
string value = ((decimal)(decimalValue * 100)).ToString("0.00"); 
Console.WriteLine(value); 

Kết quả sẽ là;

12.11 

Đây là DEMO.

Thay vào đó, bạn có thể sử dụng Nullable<T>.Value mà không có bất kỳ cuộc trò chuyện nào như;

string value = (decimalValue * 100).Value.ToString("0.00"); 

Kiểm tra để biết thêm thông tin từ Custom Numeric Format Strings

+0

Truyền tới 'thập phân' sẽ ném một' InvalidOperationException' với mã này, trong khi mã ban đầu của Pushkar sẽ dẫn đến một chuỗi rỗng. Có thể không có liên quan trong trường hợp này mặc dù. –

+0

@ChrisSinclair Không, nó sẽ không ném bất kỳ ngoại lệ nào trong trường hợp này. –

+0

Nó thực hiện khi tôi chạy nguyên văn mã trong LinqPad. EDIT: Bắn xin lỗi, tôi có nghĩa là khi 'decimalValue' là' null'. Xin lỗi, tôi quên thực sự _write_ đó. –

0
String.Format("{0:0.00}", decimalValue * 100); 

Bạn có thể sử dụng .Format() như một thay thế cho .ToString("0.00").

2

Hoặc, bạn có thể chỉ định định dạng "F2", như sau: string val = decVal.ToString("F2") vì điều này chỉ định 2 chữ số thập phân.

2

Sử dụng fixed-point ("F) format specifier.

string value = (decimalValue * 100).ToString("F"); 

Từ khoá chính xác mặc định dựa trên giá trị của NumberFormatInfo.NumberDecimalDigits tài sản mà theo mặc định có giá trị 2. Vì vậy, nếu không chỉ định một chữ số aftyer "F", nó theo mặc định chỉ rõ hai chữ số thập phân.

F0 - No decimal places 
F1 - One decimal place 
0

Kể từ decimal? không có tình trạng quá tải ToString(string format), cách dễ nhất là sử dụng String.Format thay vào đó sẽ cung cấp kết quả nhất quán với null trường hợp cho decimalValue cũng như (kết quả là một chuỗi rỗng) khi so sánh với mã ban đầu của bạn:

string value = String.Format("{0:#.##}", decimalValue * 100); 

Nhưng có một số lưu ý khác cho số khác mà bạn không được xóa trên.

Nếu bạn có một số không tạo ra giá trị lớn hơn 0, nó có hiển thị số không đứng đầu không? Tức là, đối với 0.001211, nó có hiển thị là 0.12 hoặc .12 không? Nếu bạn muốn các lãnh đạo không, sử dụng này để thay thế (chú ý sự thay đổi #.##-0.##):

string value = String.Format("{0:0.##}", decimalValue * 100); 

Nếu bạn có nhiều hơn 2 chữ số thập phân có ý nghĩa, bạn có muốn những hiển thị? Vì vậy, nếu bạn có .12113405 nó có hiển thị là 12.113405 không? Nếu vậy sử dụng:

string value = String.Format("{0:#.############}", decimalValue * 100); 

(một cách trung thực, tôi nghĩ rằng có phải là một chuỗi tốt hơn định dạng hơn, đặc biệt là khi nó chỉ hỗ trợ 12 chữ số thập phân)

Và tất nhiên nếu bạn muốn cả hai số không hàng đầu nhiều chữ số thập phân, chỉ cần kết hợp hai trên:

string value = String.Format("{0:0.############}", decimalValue * 100); 
0

trong trường hợp bạn không muốn để hạn chế đến một số lượng nhất định các chữ số thập phân:

decimal? decimalValue = .1211; 
string value = decimalValue == null 
       ? "0" 
       : decimalValue == 0 
       ? "0" 
       : (decimalValue * 100).ToString().TrimEnd('0'); 

Điều này sẽ cắt bất kỳ (nếu có) dấu 0 của chuỗi và cũng trả về "0" nếu decimalValue là không. Nếu giá trị là 0 thì "0" được trả về mà không cắt xén.

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