C # 'da ondalık bir int'e nasıl dönüştürebilirim?


227

Ondalık sayıyı int değerine nasıl dönüştürebilirim?


11
En yakın int'e yuvarlamak ya da ondalık basamaktan sonra sayıları düşürmek isteyip istemediğinizi bilmek yararlı olacaktır (yani: her zaman yuvarlak)
Dinah

128
dürüstçe gerçek soruları küçümsemek anlamıyorum. evet, cevap google üzerinde bulunabilir ama insanlar her ikinci soruyu kapatmayı bırakırsa sitenin kalitesini artırmak değil mi? Bu soru spam ya da bir şey gibi değil ve birçok yeni gelen c için yararlı olacağından eminim
jay_t55

Yanıtlar:


268

Kullan Convert.ToInt32dan mscorlibolduğu gibi

decimal value = 3.14m;
int n = Convert.ToInt32(value);

Bkz. MSDN . Ayrıca kullanabilirsiniz Decimal.ToInt32. Tekrar bakın, MSDN . Son olarak, olduğu gibi doğrudan bir döküm yapabilirsiniz

decimal value = 3.14m;
int n = (int) value;

açık döküm operatörünü kullanır. Bkz. MSDN .


10
Dikkat: Convert, belirli dönüşümler ( nullvs.'ye 0karşı "") için bazı şaşırtıcı davranışlara sahiptir . Kesinlikle esnekliğini (yani dinamik olarak yazılmış senaryolarda) ihtiyacınız olmadığı sürece
Convert'i

1
-1, çünkü bu ondalık.MaxValue ve ondalık.MinValue gibi değerler için çalışmaz ve bir OverflowException. @Will'in burada daha iyi bir cevap verdiğine inanıyorum stackoverflow.com/a/501165/39532
mezoid

8
Dikkatli olun, çünkü Convert.ToInt32ve Decimal.ToInt32farklı davranır. MSDN'den: Decimal.ToInt32- Dönüş değeri, ondalık değerin ayrılmaz bir parçasıdır; kesirli basamaklar kesilir . Convert.ToInt32- Dönüş değeri en yakın 32 bit işaretli tam sayıya yuvarlanır . Değer iki tam sayının ortasındaysa, çift sayı döndürülür; yani, 4.5, 4'e ve 5.5, 6'ya dönüştürülür.
vezucci

67

Yapamazsın.

Eh, tabii ki olabilir , ancak bir int (System.ınt32) mümkün olan her ondalık değerini tutmak için yeterince büyük değil.

Bu, int.MaxValue değerinden daha büyük bir ondalık basarsanız taşarsınız ve ondalık int.MinValue değerinden daha küçükse, taşar.

Düşük / taştığınızda ne olur? İki şeyden biri. Derlemeniz işaretlenmezse (yani, CLR yaparsanız ilgilenmez), uygulamanız değer aşımı / azlığı sonrasında devam eder, ancak int'deki değer beklediğiniz gibi olmaz. Bu, kesintili hatalara neden olabilir ve düzeltilmesi zor olabilir. Uygulamanızı, üzerinde çalıştığı önemli verilerin bozulmasına neden olabilecek bilinmeyen bir durumda sonlandırırsınız. İyi değil.

Montajınız kontrol edilirse (properties-> build-> advanced-> aritmetik taşma / taşma veya / işaretli derleyici seçeneğini kontrol edin), bir yetersiz / taşma meydana geldiğinde kodunuz bir istisna atar. Bu muhtemelen daha iyidir; ancak montajlar için varsayılan değer aşırı / düşük akışı kontrol etmemektir.

Asıl soru "ne yapmaya çalışıyorsunuz?" Gereksinimlerinizi bilmeden, kimse bu durumda ne yapmanız gerektiğini söyleyemez , açık olandan başka: YAPMAYIN.

Özellikle ilgilenmiyorsanız, buradaki yanıtlar geçerlidir. Ancak, gereken iletişim bir taşma meydana gelebilir o anlayış ve bir de senin dökme kodu sararak önemli değil kontrolsüz bloğun

unchecked
{
  // do your conversions that may underflow/overflow here
}

Bu şekilde, arkanızdan gelen insanlar umursamadığınızı anlarlar ve gelecekte birisi yapılarınızı / kontrolünü değiştirirse, kodunuz beklenmedik şekilde kırılmaz.

Eğer yapmak istediğiniz tüm parçasını bırakarak sayının kesirli kısmını damla, sen Math.Truncate kullanabilirsiniz.

decimal actual = 10.5M;
decimal expected = 10M;
Assert.AreEqual(expected, Math.Truncate(actual));

3
Giriş bir ondalık ise kaputun altında aynı şey olduğundan şüphelenmeme rağmen, Ondalık'ı kullanmaktan daha rahat hissediyorum. Ondalık yerine taban 10 olmayanlar.
Brian

7
İşaretlenmemiş bağlamlar ondalık sayılara uygulanmaz; ondalık sayılardaki işlemler ne olursa olsun OverflowExceptions atar.
Dave

46
int i = (int)d;

size yuvarlanmış numarayı verecektir.

En yakın çift sayıya yuvarlamak isterseniz (yani> .5 yuvarlanır) kullanabilirsiniz.

int i = (int)Math.Round(d, MidpointRounding.ToEven);

Genel olarak C # 'daki tüm sayısal tipler arasında döküm yapabilirsiniz. Oyuncular sırasında kaybolacak hiçbir bilgi yoksa bunu dolaylı olarak yapabilirsiniz:

int i = 10;
decimal d = i;

yine de isterseniz bunu açıkça yapabilirsiniz:

int i = 10;
decimal d = (decimal)i;

Ancak, oyuncu kadrosu aracılığıyla bilgi kaybedecekseniz, bunu açıkça yapmalısınız (bilgi kaybedebileceğinizi bildiğinizi göstermek için):

decimal d = 10.5M;
int i = (int)d;

Burada ".5" kaybediyorsun. Bu iyi olabilir, ancak bu konuda açık olmanız ve bilgileri kaybettiğinizi size göstermek için açık bir döküm yapmanız gerekir.


1
Aslında MidpointRounding.AwayFromZero istiyorsanız> * .5 her zaman burada örnek çıktıya bakarak yukarıdaki kodu deneyerek deneyimlerime dayanarak yuvarlanmasını istersiniz: msdn.microsoft.com/en-us/library/…
Elijah Lofgren

@ElijahLofgren Bu tür bağlıdır: İstatistik yapıyorsanız, ToEvenistatistik kaymasını önlemelisiniz. Ancak ücretli öğeler veya para ile işletiyorsanız AwayFromZero, doğru seçim gibi görünüyor.
mbx

22
decimal d = 2;
int i = (int) d;

Bu işe yarayacaktır.


Dikkatli olun, açık bir dönüşüm bilgisi kaybolabilir.
Phaedrus

21
Ondalıktan int'e dönüştürülürken, bilgi neredeyse her zaman kaybolacaktır, ancak bunun biraz önemli olduğuna inanıyorum.
Dinah


8

System.Decimalüyesi IConvertableolan arayüzü uygular ToInt32().

Çağrı System.Decimal.ToInt32()sizin için işe yarıyor mu ?


2
Gönderen belgeler : "Bu API, .NET Framework altyapısını destekler ve doğrudan kodundan kullanılmak üzere tasarlanmamıştır". Neden Convert.ToInt32 kullanılmıyor?
H.Wolper

7

Hızlı yuvarlama için düzgün bir hile, ondalık sayınızı bir int'e vermeden önce .5 eklemektir.

decimal d = 10.1m;
d += .5m;
int i = (int)d;

Hala gidiyor i=10, ama

decimal d = 10.5m;
d += .5m;
int i = (int)d;

Böylece yuvarlanır i=11.


5
Math.Floor ve Math.Ceiling varken bunu yapmak neden zahmet ediyor?
Badaro

O zamanlar C # için oldukça yeniydim ve bir nedenden dolayı bu işlevlerin var olduğunu fark etmedim. Aslında C / C ++ 'dan öğrendiğim bir hile, ki burada daha faydalıydı.
DeadlyBrad42

1
Ondalık değer örneğin -9,3 olsaydı?
supercat

6

Ben kullanmayı tercih Math.Round , Math.Floor , Math.Ceiling veya Math.Truncate uygun olarak açık bir şekilde ayarlanabilir yuvarlama moduna.

Hepsinin de Ondalık döndüğüne dikkat edin - Ondalık bir Int32'den daha büyük bir değer aralığına sahip olduğundan, yine de yayınlamanız (ve taşma / taşma olup olmadığını kontrol etmeniz) gerekir.

 checked {
   int i = (int)Math.Floor(d);
 }


6

Ondalık sayıyı en yakın tam sayıya yuvarlama

decimal a ;
int b = (int)(a + 0.5m);

ne zaman a = 49.9, o zamanb = 50

ne zaman a = 49.5, o zamanb = 50

ne zaman a = 49.4, o zaman b = 49vb.


0

Kutulu ondalık (yani nesne türü içinde ondalık bir değer) varsa döküm operatörü çalışmaz. Convert.ToInt32 (nesne olarak ondalık) bu durumda iyi çalışır.

Bu durum, veritabanından IDENTITY / AUTONUMBER değerleri alınırken ortaya çıkar:

SqlCommand foo = new SqlCommand("INSERT INTO...; SELECT SCOPE_IDENTITY()", conn);
int ID = Convert.ToInt32(foo.ExecuteScalar());  // works
int ID = (int)foo.ExecuteScalar();              // throws InvalidCastException

Bkz. 4.3.2 Dönüşümleri kutudan çıkarma


2
Referans için daha fazla ekleme: bunun nedeni, yalnızca aynı orijinal türün kutusundan çıkarmanızdır. Burada .NET ile çeviren SELECT SCOPE_IDENTITY()döndürür . Bir döner olarak kutulu bir doğrudan döküm edilemeyen . ya da işe yarayacaktı. numeric(38, 0)decimalfoo.ExecuteScalar()decimalobjectint(int)(decimal)foo.ExecuteScalar()Convert.ToInt32(foo.ExecuteScalar())
rageit

0

Hiçbir yanıt int aralığının dışında bir ondalık sayı dönüştürmek için gelen OverflowException / UnderflowException ile ilgili gibi görünmüyor.

int intValue = (int)Math.Max(int.MinValue, Math.Min(int.MaxValue, decimalValue));

Bu çözüm, ondalık değer int aralığının dışındaysa mümkün olan maksimum veya minimum int değerini döndürür. Değer int aralığının içindeyse Math.Round, Math.Ceiling veya Math.Floor ile biraz yuvarlama eklemek isteyebilirsiniz.

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.