2009-09-15 32 views
10

Làm thế nào tôi có thể cắt bớt chữ số hàng đầu có giá trị gấp đôi trong C#, tôi đã thử Math.Round (doublevalue, 2) nhưng không đưa ra kết quả yêu cầu. và tôi không tìm thấy bất kỳ phương pháp nào khác trong lớp Toán.Cắt ngắn số chữ số có giá trị kép trong C#

Ví dụ: tôi có giá trị 12.123456789 và tôi chỉ cần 12.12.

+3

gì nên kết quả khi bạn cung cấp cho 12,12890? – rahul

+0

Những gì ** phoenix ** được hỏi là bạn có muốn làm tròn nó đến 12,13, hoặc chỉ cắt ngắn nó thành 12,12 ...? – awe

+0

Có @awe. Thats right – rahul

Trả lời

25

EDIT: Đã được chỉ ra rằng các phương pháp tiếp cận này vòng giá trị thay vì cắt ngắn. Thật khó để cắt ngắn giá trị double vì nó không thực sự ở đúng cơ sở ... nhưng cắt ngắn giá trị decimal là khả thi hơn.

Bạn nên sử dụng chuỗi định dạng phù hợp, hoặc là custom hoặc standard, ví dụ:

string x = d.ToString("0.00"); 

hoặc

string x = d.ToString("F2"); 

Nó có giá trị là nhận thức được rằng một giá trị gấp đôi bản thân không "biết" có bao nhiêu chữ số thập phân nó có. Nó chỉ khi bạn chuyển đổi nó thành một chuỗi mà nó thực sự có ý nghĩa để làm như vậy. Sử dụng Math.Round sẽ nhận được giá trị gấp đôi gần nhất với x.xx00000 (nếu bạn thấy ý tôi) nhưng gần như chắc chắn sẽ không có giá trị chính xác x.xx00000 do cách thức các loại điểm động nhị phân hoạt động.

Nếu bạn cần điều này cho bất kỳ điều gì khác so với định dạng chuỗi, bạn nên cân nhắc sử dụng decimal để thay thế. Giá trị thực sự đại diện cho điều gì?

Tôi có các bài viết trên binary floating pointdecimal floating point trong .NET mà bạn có thể thấy hữu ích.

+0

Cảm ơn câu trả lời của bạn, tôi không muốn chuyển đổi giá trị trong chuỗi, sau đó trở lại gấp đôi một lần nữa, tôi phải lưu trữ giá trị như . var newVal = Math.Round (oldValue, 2) hoặc một số chức năng khác. – Firoz

+3

@Firoz: để chuỗi và quay lại gấp đôi sẽ không giúp bạn anyway: nếu đôi không thể đại diện cho "12.34" chính xác, sau đó bạn * sẽ * nhận được số thập phân thêm. Nó là đơn giản không thể lưu trữ một đôi với chỉ có hai thập phân. –

+0

@Firoz: Hans hoàn toàn đúng. Tôi đang thêm một vài liên kết trong câu trả lời của tôi ... –

0

số đối tượng = 12.123345534;
string.Format ({"0:00"}, number.ToString());

15

Bạn đã thử những gì? Nó hoạt động như mong đợi cho tôi:

double original = 12.123456789; 

double truncated = Math.Truncate(original * 100)/100; 

Console.WriteLine(truncated); // displays 12.12 
3

Mã này ....

double x = 12.123456789; 
Console.WriteLine(x); 
x = Math.Round(x, 2); 
Console.WriteLine(x); 

Returns này ....

12.123456789 
12.12 

kết quả mong muốn của bạn mà là khác nhau là gì?

Nếu bạn muốn giữ giá trị là gấp đôi và chỉ bất kỳ chữ số nào sau chữ số thập phân thứ hai và không thực sự làm tròn số thì bạn có thể trừ 0,005 từ số của mình để vòng đó sẽ hoạt động. Ví dụ.

double x = 98.7654321; 
Console.WriteLine(x); 
double y = Math.Round(x - 0.005, 2); 
Console.WriteLine(y); 

Sản xuất ...

98.7654321 
98.76 
+0

nếu x = 12.125 sau đó anh ta sẽ nhận được 12,13 mà dường như không phải là những gì anh ta muốn. –

+0

được chỉnh sửa để thêm tùy chọn vòng xuống –

0

Nếu bạn đang tìm kiếm để có hai điểm sau khi số thập phân không làm tròn số, sau đây nên làm việc

string doubleString = doublevalue.ToString("0.0000"); //To ensure we have a sufficiently lengthed string to avoid index issues 
Console.Writeline(doubleString 
      .Substring(0, (doubleString.IndexOf(".") +1) +2)); 

Tham số thứ hai của chuỗi là số lượng, và IndexOf trở về zero-based chỉ mục, vì vậy chúng tôi phải thêm một chỉ mục vào trước khi chúng tôi thêm 2 giá trị thập phân.

Câu trả lời này là giả định rằng giá trị không nên được làm tròn

2

tôi chắc chắn rằng có điều gì đó hơn .netty lên đó, nhưng tại sao không chỉ: -

double truncVal = Math.Truncate(val * 100)/100; 
double remainder = val-truncVal; 
+1

Loại "thập phân" có thể cung cấp ít nguy cơ lỗi làm tròn dấu phẩy động hơn. –

0

Làm thế nào về:

double num = 12.12890; 
double truncatedNum = ((int)(num * 100))/100.00; 
+0

Tôi đã làm một số điểm chuẩn và phương pháp này là 2x nhanh hơn so với Math.Truncate ban đầu. Cảm ơn bạn đã chia sẻ – mca

2

Điều này có thể hoạt động (mặc dù không được kiểm tra):

public double RoundDown(this double value, int digits) 
{ 
    int factor = Math.Pow(10,digits); 

    return Math.Truncate(value * factor)/factor; 
} 

Sau đó, bạn chỉ cần sử dụng nó như thế này:

double rounded = number.RoundDown(2); 
4
double original = 12.123456789; 

double truncated = Truncate(original, 2); 

Console.WriteLine(truncated.ToString()); 
// or 
// Console.WriteLine(truncated.ToString("0.00")); 
// or 
// Console.WriteLine(Truncate(original, 2).ToString("0.00")); 


public static double Truncate(double value, int precision) 
{ 
    return Math.Truncate(value * Math.Pow(10, precision))/Math.Pow(10, precision); 
} 
+1

Sẽ tốt hơn nếu bạn giải thích mã đó. –

0

Để sử dụng vb.net phần mở rộng này:

Imports System.Runtime.CompilerServices 

Module DoubleExtensions 

    <Extension()> 
    Public Function Truncate(dValue As Double, digits As Integer) 

     Dim factor As Integer 
     factor = Math.Pow(10, digits) 

     Return Math.Truncate(dValue * factor)/factor 

    End Function 
End Module 
Các vấn đề liên quan