Math.Floor (Double) neden Double türünde bir değer döndürür?


103

Sol taraftaki tamsayı değerini ondalık veya ikiliden almam gerekiyor. Örn: 4.6'dan 4 değerini almam gerekiyor. Math.Floor işlevini kullanmayı denedim, ancak çift değer döndürüyor, örneğin: 4.6'dan 4.0'ı döndürüyor. MSDN belgeleri, bir tamsayı değeri döndürdüğünü söylüyor. Burada bir şey mi kaçırıyorum? Yoksa aradığımı elde etmenin farklı bir yolu var mı?


2
MSDN belgeleri, bir tamsayı değeri döndürdüğünü söylüyor . MSDN belgeleri Math.Floor'un tamsayı değil, System.Double döndürdüğünü belirtir.
geniş bant

Bir tamsayı değerine etkin bir şekilde ihtiyaç vardır, ancak bu, "int" veya "long" olarak saklanabileceği anlamına gelmez. Bir "çift", tüm tamsayı değerlerini "int" değerinden çok daha geniş bir aralıkta başarıyla saklar. Mantis bölümü, taban-2 üssü olduğunda, tamsayı değerinin tüm basamaklarını depolamak için yeterli bit içermediğinde bazı tamsayı değerlerinin yuvarlanabileceğini unutmayın. 52'nin üzerine çıkarsa: tamsayı değerlerinin "çift" olarak yuvarlanması, 2 ^ 52'nin üzerindeki veya -2 ^ 52'nin altındaki tamsayılar için gerçekleşebilir, ancak sonuç yine de gösterilebilir en yakın tam sayı olacaktır; "(uzun) Kat (x)" kullanırsanız, dönüştürme büyük ölçüde yanlış olabilir.
verdy_p

Bununla birlikte, bir "çift" olarak gösterilebilecek geçerli tamsayı değerleri aralığının son derece büyük olduğunu ve mutlak değerlerin şuna kadar olduğuna dikkat edin: (1 + (1 - 2 ^ −52)) × 2 ^ 1023 ≈ 1.7976931348623157E308; "long" ile 2 ^ 63-1'den çok daha fazlasıdır. Bununla birlikte, tümü ayrı ayrı saklanabilen tamsayı aralığı daha sınırlıdır, çünkü bir "çift" mantis için yalnızca 52 bit içerir (artı en anlamlı bit için belirtilir, depolanmaz), yani "çift" yalnızca tamsayılar tam olarak oonly mutlak değerleri 2 ^ 53'ün altında olduğunda.
verdy_p

Maalesef Math.Floor (), mümkünse "Uzun" kullanarak dahili bir değişken "Sayı" türü veya aksi takdirde yalnızca büyük yuvarlanmış tamsayılar için "Çift" döndürmez. Ve standart Math kütüphanesi bu tür birleşik değişken sayı türünü işlemez. Desteklenen aralık veya hassasiyet kaybı olmadan paketlenmiş ondalık veya ikili olarak kodlanmış Uzun, Çift veya büyük tamsayılar dahil olmak üzere birleşik bir sayı türü uygulayan başka matematik kitaplıkları da vardır.
verdy_p

Yanıtlar:


146

Aralığı doublearalığında çok daha geniş intya da long. Bu kodu düşünün:

double d = 100000000000000000000d;
long x = Math.Floor(d); // Invalid in reality

Tam sayı aralığı dışında long- peki ne olmasını beklersiniz?

Tipik olarak değerin aslındaint veya aralığında olacağını bilirsiniz long, bu yüzden onu çevirirsiniz:

double d = 1000.1234d;
int x = (int) Math.Floor(d);

ancak bu oyuncu kadrosunun sorumluluğu geliştiriciye aittir, Math.Floorkendisinde değil . Aralığı dışındaki tüm değerler için bir istisna ile başarısız olması gereksiz yere kısıtlayıcı olurdu long.


2
Floor, double'ın tamsayı temsilini döndürür ve bilimsel hesaplamalar için double döndürür, bu cevap doğru değildir çünkü double 64 bit ve uzun da 64 bit içerir, ancak double doğru şekilde saklanabilse bile daha düşük anlamlı bitlerin tam basamaklarını saklayamaz. uzun süre.
Akash Kava

1
@Jon: C # 'da pozitif bir sayının nasıl negatif yapılacağına ilişkin tartışmaya nasıl ağırlık vermediniz ?: stackoverflow.com/questions/1348080/…
MusiGenesis

3
@Jon: acele etmeyin. Topluluğun, pozitif bir sayıyı -1 ile çarpmanın onu negatif yapacağını keşfettiği ortaya çıktı. StackOverflow'da her şey yolunda.
MusiGenesis

1
@javapowered: Hayır, (int) 15.0 0 değil. Başka bir şey ters gitti, ancak bundan ne olduğunu anlayamayız. Lütfen bunu gösteren kısa ama eksiksiz bir program oluşturun ve ardından bir soru sorun.
Yeniden

1
@MusiGenesis: <code> (int) IGNORE_RATIO * Volume </code>, <code> (int) 0.15 * Volume </code> olarak hesaplanır, ancak typecast ürünün sonucuna değil, yalnızca orana uygulanır ve <code> 0 * Hacim </code>, yani sıfır elde edersiniz! SİZİN hatasını çözmek için <code> (int) (IGNORE_RATIO * Volume) </code> kullanın.
verdy_p

11

MSDN'ye göre, Math.Floor (double) bir çift döndürür: http://msdn.microsoft.com/en-us/library/e0b5f0xb.aspx

İnt olarak istiyorsanız:

int result = (int)Math.Floor(yourVariable);

MSDN makalesinin nasıl yanıltıcı olabileceğini görebiliyorum, sonucun bir "tamsayı" olmasına rağmen (bu durumda tam sayı anlamına gelir) hala TYPE Double olduğunu belirtmeleri gerekirdi


Cevabın için teşekkürler. Aslında şu makaleye bakıyordum: msdn.microsoft.com/en-us/library/e0b5f0xb.aspx Ama yine de önerinizi deneyeceğim. Teşekkür ederim.

Evet doğru, en üstte "bir tamsayı döndürür" yazıyor, ancak tür aşağıda belirtilmiş: public static double Floor (double d)
Neil N

3
tamsayı =! int( answers.com/integer ) - tamsayılar olabilir saklanabilir Double(Jon'un cevaba bakınız), bir muhafaza edilemez tamsayılar sonsuz sayıda vardır ve int.
Shog9

Shog, yapamayacaklarını söylemedim. "Hala TİP Çifte kalıyor" dedim
Neil N

1
@Neil: doğru - sadece "tamsayı" (bir kümenin intadı ) ve (bir türün adı ) arasındaki farkı vurgulamak istedim .
Shog9

4

Bir sayının tam sayı kısmına ihtiyacınız varsa, sayıyı bir int. Bu, sayıyı ondalık noktadan keser.

double myDouble = 4.6;
int myInteger = (int)myDouble;

2
Negatif sayılar için çevrim işleminin ondan intfarklı davrandığına dikkat etmek önemlidir Floor. Floorher zaman en negatif sayıya intkadar kısaltılır , oysa
Magnus


0

Zemin, onu çift olarak bırakır, böylece onunla daha fazla çift hesaplama yapabilirsiniz. Bir int olarak istiyorsanız, floor'un sonucunu int olarak atayın. Negatif sayılar için taban kuralları farklı olduğundan (IIRC) orijinal double'ı int olarak çevirmeyin.


0
Convert.ToInt32(Math.Floor(Convert.ToDouble(value)))

Çıktı olarak 4.6döndürürseniz 4, bu size tam olarak istediğiniz değeri verecektir .

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.