Bir ikiliyi en yakın tam sayı değerine nasıl dönüştürebilirim?


150

Bir ikiliyi en yakın int'e nasıl dönüştürürsünüz?

Yanıtlar:


77

Math.round()Muhtemelen ile birlikte kullanınMidpointRounding.AwayFromZero

Örneğin:

Math.Round(1.2) ==> 1
Math.Round(1.5) ==> 2
Math.Round(2.5) ==> 2
Math.Round(2.5, MidpointRounding.AwayFromZero) ==> 3

6
Olmaz Convert.ToInt32()aynı şeyi yapmak, ya da sadece ondalık sonra her şeyi şerit geliyor?
The Muffin Man

211
Gerçekte bir tamsayı değil, bir çift üretir.
gatopeich

13
@Ronnie - hayır, bu tasarım gereğidir. Varsayılan olarak, Math.Round orta nokta sayılarını (x + .5) en yakın çift sayıya yuvarlar . Farklı bir davranış istiyorsanız, bunu bir bayrak aracılığıyla belirtmeniz gerekir. msdn.microsoft.com/en-us/library/system.midpointrounding.aspx
nickf

6
Ben asla! :)
Ronnie

6
Double Int değildir.
Evgeni Nabokov

274
double d = 1.234;
int i = Convert.ToInt32(d);

Referans

Şu şekilde yuvarlama kolları:

en yakın 32 bitlik 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.


7
Math.RoundGerektiği gibi bir int döndürdüğü için çok daha iyi .
Keith

10
@ robert-koritnik. Neden "geçersiz" olduğundan emin değilim. OP, tercih edilen bir yuvarlama kuralı belirtmedi ve "0,5'ten en yakın çifte yuvarla", çok eski standart kuraldır. Her zaman yuvarlamanın istenmeyen istatistiksel etkileri vardır.
Keith

@Keith: Bilmiyorum ama her zaman x.5'i yukarı ya da aşağı yuvarlamam öğretildi , ancak istatistikler için bunu yukarı veya aşağı yapmak için mantığı görebiliyorum. Bunun için teşekkürler. Not: Bu tür bir yuvarlamanın varsayılan olarak göründüğü istatistik, finans veya muhasebe alanında olmadığımı görmek açık .
Robert Koritnik

3
"Her zaman yuvarlamanın istenmeyen istatistiksel etkileri vardır" - Bu tamamen yanlıştır. 0,5'i yukarı yuvarlamak, sayıların tam olarak yarısını [0,.5)- aşağı ve tam olarak sayıların yarısı - - yukarı yuvarlar [.5,1). (.5,1.5)1'e ancak [1.5,2.5]2'ye yuvarlanarak, hatta biraz önyargılı sayılara yuvarlama .
Jim Balter

11
@JimBalter Sıfır yuvarlanmadığından, yukarı yuvarlama pozitif bir önyargı oluşturur, bu nedenle asimetrik yuvarlama olarak bilinir. Dağılımınız yeterliyse ve yuvarlama çift ya da çift sayıları saptırmıyorsa, "yarımdan eşitliğe yuvarlak" olmaz. Bkz kravat-kırılmasını yuvarlama yarı yolda .
sdds

36

Ayrıca işlevi de kullanabilirsiniz:

//Works with negative numbers now
static int MyRound(double d) {
  if (d < 0) {
    return (int)(d - 0.5);
  }
  return (int)(d + 0.5);
}

Mimariye bağlı olarak birkaç kat daha hızlıdır.


Math.Round istediğim gibi çalışmadığı için bu benim için mükemmeldi.
Hanna

@cullub evet öyle. 0.5 ekli çift d'yi bir tam sayıya dönüştürür.
Darrell

Bu benim tercih ettiğim yöntem - çok basit bir şekilde çalışıyor. Math.Round'dan (d, MidpointRounding.AwayFromZero) çok daha kısa ve okunması daha kolay ve yuvarlamayı veya yuvarlamayı seçmek için if deyimi kullanmaktan daha özlü. VE, aslında sonunda bir tamsayı, bir çift döndüren
binderbound

3
Negatif sayılar üzerindeki tuhaf davranışlar için aşağıdaki @ Eternal21'in yorumuna bakın (MyRound (-1,2) = 0)
Chris

2
Merak eden herkes için, @Chris tarafından belirtilen sorun artık muhtemelen değerin negatif olup olmadığı kontrol edilerek çözüldü.
John Weisz

14
double d;
int rounded = (int)Math.Round(d);

5

Bu sorunun eski olduğunu biliyorum, ancak benzer sorumun cevabını ararken karşılaştım. Bana verilen çok faydalı ipucunu paylaşacağımı düşündüm.

İnt'e dönüştürürken, .5aşağı doğru tahmin etmeden önce değerinize eklemeniz yeterlidir . intAşağı doğru tahmin her zaman daha düşük sayıya düştüğü için (örneğin (int)1.7 == 1), numaranız .5veya daha yüksekse, eklemek .5onu bir sonraki sayıya getirecek ve downcast'iniz intdoğru değeri döndürmelidir. (örneğin (int)(1.8 + .5) == 2)


13
Sorun, negatif değerleri bu şekilde dönüştürmeye çalışırsanız. Örneğin -1.25, 0'a eşit olacak (-1.25 + 0.5 = 0.75 ve int'e dönüştürüldüğünde 0'dır). Yani negatif değerlerden 0,5 çıkarmanız gerekir.
Eternal 21

Kullanılabilir+ 0.5 * Math.Abs(d)
TaW


-1

Unity için Mathf.RoundToInt kullanın .

using UnityEngine;

public class ExampleScript : MonoBehaviour
{
    void Start()
    {
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.0f));
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.2f));
        // Prints 11
        Debug.Log(Mathf.RoundToInt(10.7f));
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.5f));
        // Prints 12
        Debug.Log(Mathf.RoundToInt(11.5f));

        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.0f));
        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.2f));
        // Prints -11
        Debug.Log(Mathf.RoundToInt(-10.7f));
        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.5f));
        // Prints -12
        Debug.Log(Mathf.RoundToInt(-11.5f));
    }
}

Kaynak

public static int RoundToInt(float f) { return (int)Math.Round(f); }

Q, Unity'den bahsetmez veya etiketlemez.
XenoRo

@XenoRo Unity'yi kullanırken benzer cevaplar arayanlar için bu eski soruyu cevaplıyordum.
zwcloud

3
Bilgi paylaşımı için kendi sorularınızı cevaplayabilirsiniz. Bu gibi durumlarda API'ye özel (bu durumda Unity) ayrı bir soru oluşturun. Cevaplar sorulara uygun olmalıdır. Aksi takdirde, yuvarlama işlevine sahip her bir C # API için burada bir yanıt olabilir.
XenoRo

-2

Int düğmesi sporu yapan bilimsel bir hesap makinesi geliştiriyorum. Aşağıdakilerin basit ve güvenilir bir çözüm olduğunu buldum:

double dblInteger;
if( dblNumber < 0 )
   dblInteger = Math.Ceiling(dblNumber);
else
   dblInteger = Math.Floor(dblNumber);

Math.Round bazen beklenmedik veya istenmeyen sonuçlar üretir ve tamsayıya açık dönüştürme (cast veya Convert.ToInt ... aracılığıyla) genellikle daha yüksek kesinlikli sayılar için yanlış değerler üretir. Yukarıdaki yöntem her zaman işe yarıyor gibi görünüyor.


2
bu tüm negatifleri ve tüm pozitif sayıları yuvarlamaz mı? Bu mutlaka "en temiz" tam sayı değildir.
Tim Pohlmann

bu en yakın numara değil.
Samer Aamar

1
1,99 verildiğinde, bu 1,0 değerini verir.
Jon Schneider
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.