Cách tốt nhất để lấy một phần số nguyên của số thập phân


89

Cách tốt nhất để trả về phần số nguyên của một số thập phân (trong c #) là gì? (Điều này phải hoạt động đối với những số rất lớn có thể không vừa với một số nguyên).

GetIntPart(343564564.4342) >> 343564564
GetIntPart(-323489.32) >> -323489
GetIntPart(324) >> 324

Mục đích của việc này là: Tôi đang chèn vào trường thập phân (30,4) trong db và muốn đảm bảo rằng tôi không cố chèn một số quá dài cho trường. Xác định độ dài của phần số nguyên của số thập phân là một phần của hoạt động này.


Bạn không thể lấy phần int; bạn có thể lấy toàn bộ phần số và bỏ phần phân số. Toàn bộ phần số của một số thập phân có thể dễ dàng làm tràn một số int và ném hoặc quấn xung quanh, âm thầm giết mã của bạn.

1
Chà, đó là lý do tại sao câu hỏi này không đơn giản như nó có vẻ. Tôi cần điều này để làm việc với số lượng rất lớn một cách đáng tin cậy cũng như đối với số lượng nhỏ. Tuy nhiên, "whole number" chính xác hơn "int" - tôi sẽ diễn đạt lại ở trên.
Yaakov Ellis

Câu trả lời:


212

Nhân tiện, (int) Decimal.MaxValue sẽ tràn. Bạn không thể lấy phần "int" của một số thập phân vì số thập phân quá lớn để đặt trong hộp int. Chỉ cần kiểm tra ... nó thậm chí quá lớn trong một thời gian dài (Int64).

Nếu bạn muốn bit của một giá trị Thập phân ở TRÁI của dấu chấm, bạn cần thực hiện điều này:

Math.Truncate(number)

và trả về giá trị là ... MỘT KHOẢNG CÁCH hoặc một ĐÔI.

chỉnh sửa: Cắt ngắn chắc chắn là chức năng chính xác!


Vì vậy, kết quả là số thập phân hoặc kép sẽ không bao giờ có bất kỳ thứ gì sau dấu chấm nhưng không có đối tượng tích hợp sẵn để lưu trữ kết quả dưới dạng "int" (không có chữ số thập phân) có vẻ hơi khập khiễng?
Coops

@CodeBlend: Không có nhiều lời kêu gọi thiết kế khuôn khổ xung quanh mong muốn mất độ chính xác.

@CodeBlend: Bạn vẫn sẽ mất độ chính xác vì bạn đang cắt các giá trị thập phân của một số. Không chắc bạn đang nhận được gì.

Không chắc điều này sẽ hoạt động hay không. Bởi vì Math.Truncate (-5.99999999999999999) trả về -6.0 cho tôi ... !!
Bharat Mori

@Bharat Mori: Có vẻ như -5.99999999999999999 được làm tròn thành -6.0 trước khi cắt ngắn. Hãy thử với hậu tố "m" và nó sẽ hoạt động. Math.Truncate (-5,99999999999999999m) cho kết quả -5.
Henry


4

Phụ thuộc vào những gì bạn đang làm.

Ví dụ:

//bankers' rounding - midpoint goes to nearest even
GetIntPart(2.5) >> 2
GetIntPart(5.5) >> 6
GetIntPart(-6.5) >> -6

hoặc là

//arithmetic rounding - midpoint goes away from zero
GetIntPart(2.5) >> 3
GetIntPart(5.5) >> 6
GetIntPart(-6.5) >> -7

Mặc định luôn là cái cũ, có thể là một bất ngờ nhưng rất có ý nghĩa .

Dàn diễn viên rõ ràng của bạn sẽ làm:

int intPart = (int)343564564.5
// intPart will be 343564564

int intPart = (int)343564565.5
// intPart will be 343564566

Theo cách bạn diễn đạt câu hỏi, có vẻ như đây không phải là điều bạn muốn - bạn muốn xếp nó vào bất cứ lúc nào.

Tôi sẽ làm:

Math.Floor(Math.Abs(number));

Cũng kiểm tra kích thước của bạn decimal- chúng có thể khá lớn, vì vậy bạn có thể cần sử dụng a long.


(dài) tràn Decimal.MaxValue.

Điểm khá - Tôi đoán đó là lý do tại sao Math.Truncate (thập phân) trả về số thập phân.
Keith

Trong C #, truyền đến int không làm tròn, vì vậy (int) 0.6f sẽ là 0 và (int) 343564565.5 sẽ kết thúc bằng 5, không phải 6. Hãy thử tại đây: repl.it/repls/LuxuriousCheerfulDistributeddatabase
sschmidTU

0

Bạn chỉ cần truyền nó, chẳng hạn như:

int intPart = (int)343564564.4342

Nếu bạn vẫn muốn sử dụng nó dưới dạng số thập phân trong các phép tính sau này, thì Math.Truncate (hoặc có thể là Math.Floor nếu bạn muốn một hành vi nhất định cho các số âm) là hàm bạn muốn.


5
Đây là sai sai sai sai. Nếu kết quả lớn hơn những gì Int32 có thể giữ, nó sẽ ném ra một ngoại lệ hoặc (thậm chí tệ hơn !!!) âm thầm tràn và quấn ngược lại, cho bạn một kết quả hoàn toàn không chính xác mà bạn không hề biết về nó.

2
Không, nó không sai . Nó nhiều không hợp lệ cho các giá trị số thập phân / dấu phẩy động rất lớn, nhưng nó hoàn toàn ổn cho hầu hết các trường hợp. Các con số thường bị hạn chế ở mức đủ thấp khi mã hóa, vì vậy điều này không phải là vấn đề. Ngoài ra, tôi đã cung cấp giải pháp Math.Truncate hoạt động cho tất cả các giá trị.
Noldorin

2
Tôi hiểu tại sao bạn lại tức giận với tôi. Thực tế là câu trả lời của bạn là sai. Bạn đang nói với anh ta rằng hãy nắm lấy cơ hội để nó không bị phá vỡ bởi vì, này, rất nhiều con số nhỏ. Đó là một rủi ro ngu ngốc để chấp nhận. Bạn nên chỉnh sửa câu trả lời của mình và xóa mọi thứ trừ Math.Truncate là phần chính xác duy nhất của nó.

1
Bạn biết họ nói gì về ASSUME. Ngoài ra, giả định của bạn đặc biệt khủng khiếp. Đó có phải là viêm không? Tôi đoán bạn có thể nói như vậy. Bạn cũng có thể nói rằng việc bảo ai đó làm điều gì đó ngu ngốc sẽ khiến họ gặp rắc rối trên đường đi cũng là hành vi gây viêm nhiễm, nếu không nói là phi đạo đức.

1
Quả thực điều đó sẽ sai nếu tôi định đưa ra một câu trả lời sai lệch. Đúng như vậy, tôi chỉ đơn giản là cố gắng giúp đỡ. Nếu tôi hiểu sai một chút hoặc không hoàn toàn đánh giá cao câu hỏi, điều đó là đủ công bằng - không có tội gì cả. Vậy tại sao chúng ta lại tranh cãi? Tất cả chúng tôi đồng ý Truncate là câu trả lời đúng.
Noldorin

0

Cách rất dễ dàng để tách giá trị và giá trị phần phân số của nó.

double  d = 3.5;
int i = (int)d;
string s = d.ToString();
s = s.Replace(i + ".", "");

s là phần thập phân = 5 và
i là giá trị nguyên = 3


1
Xem câu trả lời hàng đầu ở trên. Điều này không hoạt động vì (int)Decimal.MaxValuesẽ tràn.
Yaakov Ellis

0

Tôi hy vọng sẽ giúp bạn.

/// <summary>
/// Get the integer part of any decimal number passed trough a string 
/// </summary>
/// <param name="decimalNumber">String passed</param>
/// <returns>teh integer part , 0 in case of error</returns>
private int GetIntPart(String decimalNumber)
{
    if(!Decimal.TryParse(decimalNumber, NumberStyles.Any , new CultureInfo("en-US"), out decimal dn))
    {
        MessageBox.Show("String " + decimalNumber + " is not in corret format", "GetIntPart", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return default(int);
    } 

    return Convert.ToInt32(Decimal.Truncate(dn));
}

-2
   Public Function getWholeNumber(number As Decimal) As Integer
    Dim round = Math.Round(number, 0)
    If round > number Then
        Return round - 1
    Else
        Return round
    End If
End Function

1
Câu trả lời được chấp nhận — được đăng cách đây hơn tám năm — giải thích tại sao câu trả lời này sai. Phạm vi của decimallà lớn hơn nhiều so với của int. Ngoài ra, đây không phải là một câu hỏi VB.
Joe Farrell

@JoeFarrell - nếu bạn cảm thấy câu trả lời sai, bạn có thể cân nhắc từ chối nó ngoài việc chỉ để lại nhận xét về hiệu ứng. Tuy nhiên, đừng gắn cờ nó (không phải tôi đang nói là bạn có). Đó là một nỗ lực để trả lời câu hỏi. Nó có thể sai ngôn ngữ, nó có thể sai ngay cả trong VB, nhưng đó là một sự cố gắng. Ví dụ, hãy xem " Khi một câu trả lời trả lời câu hỏi sai, đó có phải là Câu trả lời không? ".
Wai Ha Lee,
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.