Lấy phần thập phân từ một nhân đôi


83

Tôi muốn nhận số sau dấu chấm thập phân ở dạng số nguyên. Ví dụ: chỉ 05 từ 1,05 hoặc từ 2,50 chỉ 50 chứ không phải 0,50


15
2,50 chỉ là 2,5. Tôi cho rằng bạn đang nói về chuỗi.
— Tim Schmelter 23/10/12

3
Bạn có luôn trả về hai chữ số đầu tiên sau chữ số thập phân không? Là đầu vào một decimal, float, string, ...?
— Greg

3
Một ví dụ về cách sử dụng sẽ giúp bạn nhận được câu trả lời chất lượng cho lần sau.
— tmesser

vâng chỉ TOWO chữ số, đầu vào là số thập phân
— user1095549

3
Nhóm phát triển C # nên lúng túng (và phải hành động) rằng thao tác rất phổ biến này không có hàm Math.chức năng đơn lẻ nào như Math.DecimalPart (kép x) hoặc cái gì đó. Có quá nhiều cách "bạn đã thử cái này, bạn đã nghĩ về cái kia" cho một điều mà nhiều người trong chúng ta cần phải làm thường xuyên.
— philologon

Câu trả lời:


-20

Cập nhật câu trả lời

Ở đây tôi đưa ra 3 cách tiếp cận giống nhau.

[1] Giải toán bằng Math.Truncate

 var float_number = 12.345;
 var result = float_number - Math.Truncate(float_number);

// đầu vào: 1.05
// đầu ra: "0.050000000000000044"

// đầu vào: 10.2
// đầu ra: 0,19999999999999929

Nếu đây không phải là kết quả như bạn mong đợi, thì bạn phải thay đổi kết quả thành dạng bạn muốn (nhưng bạn có thể thực hiện lại một số thao tác chuỗi.)

[2] sử dụng hệ số nhân [là 10 theo lũy thừa của N (ví dụ: 10² hoặc 10³) trong đó N là số chữ số thập phân]

       // multiplier is " 10 to the power of 'N'" where 'N' is the number 
       // of decimal places
       int multiplier = 1000;  
       double double_value = 12.345;
       int double_result = (int)((double_value - (int)double_value) * multiplier);

// đầu ra 345

Nếu số vị trí thập phân không được cố định, thì cách tiếp cận này có thể tạo ra vấn đề.

[3] sử dụng "Cụm từ thông dụng (REGEX)"

chúng ta nên rất cẩn thận khi viết các giải pháp với chuỗi. Điều này sẽ không thích hợp ngoại trừ một số trường hợp.

Nếu bạn định thực hiện một số phép toán chuỗi với chữ số thập phân, thì điều này sẽ thích hợp hơn

    string input_decimal_number = "1.50";
    var regex = new System.Text.RegularExpressions.Regex("(?<=[\\.])[0-9]+");
    if (regex.IsMatch(input_decimal_number))
    {
        string decimal_places = regex.Match(input_decimal_number).Value;
    }

// đầu vào: "1.05"
// đầu ra: "05"

// đầu vào: "2.50"
// đầu ra: "50"

// đầu vào: "0.0550"
// đầu ra: "0550"

bạn có thể tìm thêm về Regex trên http://www.regexr.com/


Hãy cẩn thận với ToString () vì nó sẽ không trả về phần thập phân cho các số nguyên, nghĩa là nếu MyValue là 3, MyValue.ToString () sẽ trả về "3" vì vậy Split ('.') [1] sẽ ném. Cân nhắc chỉ định định dạng một cách rõ ràng cho số vị trí thập phân bạn cần: MyValue.ToString ("F2"). Split ('.') [1]
— Alex Beynenson

7
Giải pháp này chậm hơn khoảng hai bậc độ lớn so với bất kỳ giải pháp nào khác trên trang này và chậm hơn bốn bậc độ lớn so với câu trả lời của riêng tôi.
— tmesser

1
Giải pháp này dành riêng cho văn hóa. Ví dụ, ở tiếng Nga và tiếng Anh-Mỹ có dấu phân cách thập phân khác nhau (tương ứng với dấu phẩy và dấu chấm). Vì vậy, mã này sẽ không thành công khi cài đặt các nền văn hóa khác.
— Yury Schkatula

2
Giải pháp này phân chia trên ., không phải lúc nào cũng là dấu phân cách thập phân (nghĩa là ở Châu Âu, dấu phân tách thập phân là ,). Bạn phải thêm CultureInfo.Invariantđể làm cho nó trở nên quốc tế. Mặc dù nó dễ dàng hơn chỉ để sử dụng x - Math.Truncate(x)và bạn có thể ảo diệu với kết quả đó.
— Abel

3
@Kiquenet Bởi vì đó là bản sửa đổi thứ 7. Đây là câu trả lời ban đầu: stackoverflow.com/revisions/19374418/1
— Manfred Radlwimmer

196

tốt nhất trong cách tốt nhất là:

var floatNumber = 12.5523;

var x = floatNumber - Math.Truncate(floatNumber);

kết quả bạn có thể chuyển đổi theo cách bạn muốn


10
Điều này sẽ là câu trả lời được chấp nhận, một giải pháp Toán cho một câu hỏi Toán, mà không cần tất cả những gì mucking tẻ nhạt về trong thao tác chuỗi
— johnc

19
Tôi nghĩ rằng giải pháp này có một "vấn đề". Nếu floatNumber là "10.2", thì biến x sẽ giống như "0.19999999999999929". Ngay cả khi điều này hoạt động như mong đợi, kết quả sẽ là "0,2" chứ không phải "2".
— Dherik

4
Giá trị @Dherik Float và Double luôn có lỗi nhỏ trong phép trừ ở vài vị trí thập phân cuối cùng. Bạn không nên coi chúng là quan trọng. Nếu bạn thực sự cần loại chính xác đó, bạn nên sử dụng loại Decimal. Nếu bạn không thể chuyển sang Hệ thập phân (hoặc chỉ là không muốn), thì bạn phải theo dõi độ chính xác dự kiến ​​bằng cách nào đó và giải thích điều đó trong các phép toán so sánh. Tôi thường sử dụng 4 chữ số thập phân, nhưng có thể có ngoại lệ cho điều đó.
— philologon

Từ msdn.microsoft.com/en-us/library/... : "Bởi vì một số con số không thể được đại diện chính xác như các giá trị nhị phân phân đoạn, số dấu chấm động có thể số thực chỉ là xấp xỉ"
— philologon

1
Nhận xét cuối cùng: Sử dụng Math.Truncate là mục đích của tác giả của thư viện Toán cho loại tình huống này. Câu trả lời của @Matterai nên được chấp nhận.
— philologon

80
var decPlaces = (int)(((decimal)number % 1) * 100);

Điều này cho rằng số của bạn chỉ có hai chữ số thập phân.


(318.40d % 1) * 100kết quả đầu ra 39.9999999999977, bạn có thể sử dụng casting để có được xung quanh các lỗi làm tròn:var decPlaces = (int)(((decimal)number % 1) * 100);
— orad

@orad Vui lòng gọi đến đó - các số dấu phẩy động luôn có những điểm không chính xác nhỏ này, vì vậy việc truyền nó là khá thận trọng để đảm bảo hành vi nhất quán. Tôi sẽ cập nhật câu trả lời của mình, mặc dù về mặt kỹ thuật của Matterai vẫn đúng hơn.
— tmesser

26

Có một giải pháp gọn gàng hơn và nhanh hơn cách tiếp cận 'Math.Truncate':

double frac = value % 1;

5
lưu ý: đối với các giá trị âm, nó là số âm : -12,34% 1 => -0,33999999999999986
— Alex Poca

15

Giải pháp không có vấn đề làm tròn:

double number = 10.20;
var first2DecimalPlaces = (int)(((decimal)number % 1) * 100);
Console.Write("{0:00}", first2DecimalPlaces);

Kết quả đầu ra: 20

Lưu ý nếu chúng tôi không ép kiểu sang thập phân, nó sẽ xuất ra 19.

Cũng thế:

  • cho 318.40đầu ra: 40(thay vì 39)
  • cho 47.612345đầu ra: 61(thay vì 612345)
  • cho 3.01đầu ra: 01(thay vì 1)

Nếu bạn đang làm việc với các con số tài chính, chẳng hạn như trong trường hợp này, bạn đang cố gắng lấy một phần xu của số tiền giao dịch, hãy luôn sử dụng decimalkiểu dữ liệu.

Cập nhật:

Phần sau cũng sẽ hoạt động nếu xử lý nó dưới dạng chuỗi (xây dựng dựa trên câu trả lời của @ SearchForKnowledge).

10.2d.ToString("0.00", CultureInfo.InvariantCulture).Split('.')[1]

Sau đó, bạn có thể sử dụng Int32.Parseđể chuyển nó thành int.


1
— Thích

Tôi đã sử dụng cái này ... 10.2d.ToString ("0,00", CultureInfo.InvariantCulture) .Split ('.') [1]
— Ziggler

10

Cách tốt hơn -

        double value = 10.567;
        int result = (int)((value - (int)value) * 100);
        Console.WriteLine(result);

Đầu ra -

56

2
Đã không kiểm tra, nhưng điều này bị mắc phải không chính xác phao, không?
— mafu

Đối với 10.20nó sẽ xuất ra 19. Hãy xem câu trả lời của tôi.
— orad

10

Biến thể đơn giản nhất có thể là Math.truncate ()

double value = 1.761
double decPart = value - Math.truncate(value)

2

Tôi đoán chủ đề này đã cũ nhưng tôi không thể tin rằng không ai đã đề cập đến Math.

//will always be .02 cents
(10.02m - System.Math.Floor(10.02m))

Dành cho những người siêu lười biếng:double fract(double x) { return x - System.Math.Floor(x); }
— Felipe Gutierrez

1
var result = number.ToString().Split(System.Globalization.NumberDecimalSeparator)[2]

Trả về nó dưới dạng một chuỗi (nhưng bạn luôn có thể chuyển nó trở lại int) và giả sử rằng số có dấu "." một vài nơi.


1
int last2digits = num - (int) ((double) (num /  100) * 100);

Câu hỏi là lấy 2 chữ số thập phân đầu tiên. Đối với số 318.401567dđầu ra giải pháp của bạn 0.401567ở nơi 40mong đợi.
— orad

0
    public static string FractionPart(this double instance)
    {
        var result = string.Empty;
        var ic = CultureInfo.InvariantCulture;
        var splits = instance.ToString(ic).Split(new[] { ic.NumberFormat.NumberDecimalSeparator }, StringSplitOptions.RemoveEmptyEntries);
        if (splits.Count() > 1)
        {
            result = splits[1];
        }
        return result;
    }

0

Đây là một phương pháp mở rộng tôi đã viết cho một tình huống tương tự. Ứng dụng của tôi sẽ nhận các số ở định dạng 2,3 hoặc 3,11 trong đó thành phần nguyên của số đại diện cho năm và thành phần phân số đại diện cho tháng.

// Sample Usage
int years, months;
double test1 = 2.11;
test1.Split(out years, out months);
// years = 2 and months = 11

public static class DoubleExtensions
{
    public static void Split(this double number, out int years, out int months)
    {
        years = Convert.ToInt32(Math.Truncate(number));

        double tempMonths = Math.Round(number - years, 2);
        while ((tempMonths - Math.Floor(tempMonths)) > 0 && tempMonths != 0) tempMonths *= 10;
        months = Convert.ToInt32(tempMonths);
    }
}

0

Đó có thể là chi phí cao nhưng sẽ hoạt động.

double yourDouble = 1.05;
string stringForm = yourDouble.ToString();
int dotPosition = stringForm.IndexOf(".");
decimal decimalPart = Decimal.Parse("0" + stringForm.Substring(dotPosition));

Console.WriteLine(decimalPart); // 0.05

0
 string input = "0.55";
    var regex1 = new System.Text.RegularExpressions.Regex("(?<=[\\.])[0-9]+");
    if (regex1.IsMatch(input))
    {
        string dp= regex1.Match(input ).Value;
    }

1
Sẽ thật tuyệt nếu bạn có thể thêm mô tả về cách regex giúp giải quyết vấn đề
— Cleptus

-1

Bạn có thể xóa dấu chấm .khỏi dấu đôi mà bạn đang cố lấy các số thập phân bằng cách sử dụngRemove() hàm sau khi chuyển đổi dấu kép thành chuỗi để bạn có thể thực hiện các thao tác cần thiết trên nó

Hãy xem xét có một _Doublegiá trị gấp đôi 0.66781, đoạn mã sau sẽ chỉ hiển thị các số sau dấu chấm .là66781

double _Double = 0.66781; //Declare a new double with a value of 0.66781
string _Decimals = _Double.ToString().Remove(0, _Double.ToString().IndexOf(".") + 1); //Remove everything starting with index 0 and ending at the index of ([the dot .] + 1) 

Giải pháp khác

Bạn cũng có thể sử dụng lớp Pathnày thực hiện các hoạt động trên các cá thể chuỗi theo cách đa nền tảng

double _Double = 0.66781; //Declare a new double with a value of 0.66781
string Output = Path.GetExtension(D.ToString()).Replace(".",""); //Get (the dot and the content after the last dot available and replace the dot with nothing) as a new string object Output
//Do something

-2

Sử dụng regex: Regex.Match("\.(?\d+)")Ai đó sửa cho tôi nếu tôi sai ở đây


Không phải là rất phổ biến với Regex.Matchnhưng tôi đã nhận lỗi sau khi cố gắng để có được giá trị của chữ số thập phânArgumentException was unhandled: parsing "\.(?\d+)" - Unrecognized grouping construct.
— Picrofo phần mềm

-2

Nó rất đơn giản

       float moveWater =  Mathf.PingPong(theTime * speed, 100) * .015f;
       int    m = (int)(moveWater);
       float decimalPart= moveWater -m ;

       Debug.Log(decimalPart);

-2

Tại sao không sử dụng int y = value.Split('.')[1];?

Các Split()chức năng tách giá trị vào nội dung riêng biệt và 1được xuất ra giá trị thứ 2 sau.


Điều này sẽ hoạt động:Int32.Parse((12.05123d.ToString("0.00").Split('.')[1]))
— orad,

Bởi vì bạn đang truyền nó thành một chuỗi để thực hiện thao tác với chuỗi. Tôi không nghĩ rằng bạn nhận ra điều này chậm chạp và lãng phí đến mức nào.
— dmarra
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 cookie và Chính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.