Ondalık sayının tam sayı kısmını almanın en iyi yolu


91

Ondalığın tam sayı kısmını (c # cinsinden) döndürmenin en iyi yolu nedir? (Bu, int'e uymayabilecek çok büyük sayılar için çalışmalıdır).

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

Bunun amacı şudur: db'de ondalık (30,4) bir alana ekliyorum ve alan için çok uzun olan bir sayı girmeye çalışmadığımdan emin olmak istiyorum. Ondalığın tam sayı kısmının uzunluğunu belirlemek bu işlemin bir parçasıdır.


İnt kısmını alamazsınız; tam sayı kısmını alabilir ve kesirli kısmı atabilirsiniz. Bir Decimal'in tam sayı kısmı, bir int'i kolayca aşabilir ve kodunuzu sessizce öldürerek atabilir veya etrafına sarabilir.

1
İşte bu yüzden bu soru göründüğü kadar basit değil. Bunun çok büyük sayılar için olduğu kadar küçük sayılar için olduğu kadar güvenilir şekilde çalışmasına ihtiyacım var. Bununla birlikte, "tam sayı" "int" den daha doğrudur - yukarıda yeniden ifade edeceğim.
Yaakov Ellis

Yanıtlar:


215

Bu arada çocuklar, (int) Decimal.MaxValue taşacak. Ondalık sayının "int" kısmını alamazsınız çünkü ondalık, int kutusuna konulamayacak kadar büyüktür. Sadece kontrol ettim ... uzun bir süre için bile çok büyük (Int64).

Ondalık değerin bitini noktanın SOLU olarak istiyorsanız, bunu yapmanız gerekir:

Math.Truncate(number)

ve değeri ... A DECIMAL veya DOUBLE olarak döndürür.

düzenleme: Kesmek kesinlikle doğru işlevdir!


Yani sonuç ondalık veya çifttir ki bu noktadan sonra hiçbir zaman hiçbir şey içermeyecektir, ancak sonucu biraz yetersiz görünen bir "int" (ondalık basamaksız) olarak depolamak için yerleşik nesne yoktur?
Coops

@CodeBlend: Hassasiyeti kaybetme arzusu etrafında çerçeve tasarlamaya pek gerek yok.

@CodeBlend: Bir sayının ondalık değerlerini kesdiğiniz için yine de hassasiyeti kaybedersiniz. Neye ulaştığından emin değilim.

Bunun işe yarayıp yaramayacağından emin değilim. Math.Truncate (-5.99999999999999999) benim için -6.0 döndürdüğünden ... !!
Bharat Mori

@Bharat Mori: Görünüşe göre -5.99999999999999999, kesmeden önce -6.0'a yuvarlanmış. "M" sonekini deneyin ve işe yarayacaktır. Math.Truncate (-5.99999999999999999m) -5 verir.
Henry


4

Ne yaptığına bağlı.

Örneğin:

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

veya

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

Varsayılan her zaman eskidir, bu sürpriz olabilir ancak çok mantıklıdır .

Açık oyuncu kadronuz şunları yapacak:

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

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

Soruyu dile getirme şeklinden, istediğin bu değil gibi görünüyor - her seferinde zemine oturtmak istiyorsun.

Yapardım:

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

Ayrıca boyutunuzu da kontrol edin decimal- oldukça büyük olabilirler, bu nedenle bir long.


(uzun) Decimal.MaxValue taşmaları.

Doğru nokta - Sanırım Math.Truncate (decimal) ondalık döndürür.
Keith

C # 'da int'e çevrim yuvarlanmaz, bu nedenle (int) 0.6f 0 olur ve (int) 343564565.5 6 değil 5 ile biter. Burayı
sschmidTU

0

Sadece bunu yapman gerekiyor:

int intPart = (int)343564564.4342

Hala onu sonraki hesaplamalarda ondalık sayı olarak kullanmak istiyorsanız, Math.Truncate (veya negatif sayılar için belirli bir davranış istiyorsanız muhtemelen Math.Floor) istediğiniz işlevdir.


5
Bu yanlış, yanlış, yanlış. Sonuç bir Int32'nin tutabileceğinden daha büyükse, ya bir istisna atar ya da (daha da kötüsü !!!) sessizce taşar ve geri sarılır, siz bile bilmeden tamamen yanlış bir sonuç verir.

2
Hayır, yanlış değil . Çoğu, çok büyük ondalık sayılar / kayan nokta değerleri için geçerli değildir, ancak çoğu durumda mükemmeldir. Sayılar, kodlama sırasında genellikle yeterince düşük olmakla sınırlandırılır, bu nedenle bunun bir sorun olması gerekmez. Ayrıca, tüm değerler için çalışan bir Math.Truncate çözümü sağladım.
Noldorin

2
Bana neden kızdığını anlıyorum. Gerçek şu ki, cevabınız yanlış. Ona kırılmaması için bir şans vermesini söylüyorsunuz çünkü, hey, birçok sayı küçük. Alması aptalca bir risk. Cevabınızı düzenlemeli ve Math.Truncate dışındaki her şeyi tek doğru kısım olarak kaldırmalısınız.

1
ASSUME hakkında ne derler bilirsiniz. Ayrıca, varsayımınız özellikle berbat. Bu iltihaplı mı? Sanırım bunu söyleyebilirsin. Ayrıca, birine yolun aşağısında sorunlara neden olacak aptalca bir şey yapmasını söylemenin, etik dışı değilse de kışkırtıcı olduğunu da söyleyebilirsin.

1
Aslında yanıltıcı bir cevap vermek isteseydim bu yanlış olur. Olduğu gibi, sadece yardım etmeye çalışıyordum. Biraz yanlış anlamaktan veya soruyu tam olarak anlamamaktan suçluysam, bu yeterince adil - bu suç değil. Öyleyse neden şimdi tartışıyoruz? Hepimiz Truncate'in doğru cevap olduğuna katılıyoruz.
Noldorin

0

Değeri ve kesirli parça değerini ayırmanın çok kolay yolu.

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

s kesirli kısım = 5 ve
i tamsayı = 3 olarak değer


1
Yukarıdaki en iyi yanıta bakın. Bu işe yaramıyor çünkü (int)Decimal.MaxValuetaşacak.
Yaakov Ellis

0

Umarım size yardımcı olur

/// <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
Sekiz yıldan daha önce yayınlanan kabul edilen cevap, bu cevabın neden yanlış olduğunu açıklıyor. Aralığı, aralığından decimalçok daha büyük int. Ayrıca, bu bir VB sorusu değil.
Joe Farrell

@JoeFarrell - cevabın yanlış olduğunu düşünüyorsanız, etkiye bir yorum bırakmanın yanı sıra olumsuz oy kullanmayı da düşünebilirsiniz. Ancak işaretlemeyin (sahip olduğunuzu söylediğimden değil). Bu bir var girişimi soruyu cevaplamak için. Yanlış dilde olabilir, VB'de bile yanlış olabilir ama bu bir girişimdir. Örneğin, " Bir yanıt yanlış soruyu yanıtladığında, Yanıt Değil mi? " Konusuna bakın .
Wai Ha Lee
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.