Jak mogę zamienić double na najbliższą wartość całkowitą?

147

Jak zamienić double na najbliższe int?

leora
źródło

Odpowiedzi:

78

Użyj Math.round(), ewentualnie w połączeniu zMidpointRounding.AwayFromZero

na przykład:

Math.Round(1.2) ==> 1
Math.Round(1.5) ==> 2
Math.Round(2.5) ==> 2
Math.Round(2.5, MidpointRounding.AwayFromZero) ==> 3
nickf
źródło
6
Nie Convert.ToInt32()zrobi tego samego, czy po prostu usunie wszystko po przecinku?
The Muffin Man
208
W rzeczywistości nie tworzy liczby całkowitej, ale podwójną.
gatopeich
13
@Ronnie - nie, to jest zgodne z projektem. Domyślnie Math.Round zaokrągla liczby środkowe (x + .5) do najbliższej parzystej liczby. Jeśli chcesz innego zachowania, musisz określić to za pomocą flagi. msdn.microsoft.com/en-us/library/system.midpointrounding.aspx
nickf
6
Cóż ja nigdy! :)
Ronnie,
5
Double nie jest Int.
Evgeni Nabokov
267
double d = 1.234;
int i = Convert.ToInt32(d);

Odniesienie

Uchwyty zaokrągleń w ten sposób:

zaokrąglone do najbliższej 32-bitowej liczby całkowitej ze znakiem. Jeśli wartość jest w połowie między dwiema liczbami całkowitymi, zwracana jest liczba parzysta; to znaczy 4,5 jest konwertowane na 4, a 5,5 jest konwertowane na 6.

John Sheehan
źródło
7
Znacznie lepiej, Math.Roundponieważ zwraca int zgodnie z wymaganiami.
Keith,
10
@ robert-koritnik. Nie wiem, dlaczego jest to „nieprawidłowe”. OP nie określił preferowanej reguły zaokrąglania, a „zaokrąglenie 0,5 do najbliższej parzystej” jest standardową zasadą od dawna. Zawsze zaokrąglanie w górę ma niepożądane efekty statystyczne.
Keith
@Keith: Nie wiem, ale zawsze uczono mnie zaokrąglać x.5 w górę, ale widzę powody, aby robić to w górę lub w dół dla statystyk. Dziękuję za to. PS Wyraźnie widać, że nie zajmuję się statystyką, finansami ani księgowością, gdzie tego rodzaju zaokrąglanie wydaje się być domyślne .
Robert Koritnik
3
„Zawsze zaokrąglanie w górę ma niepożądane efekty statystyczne” - to po prostu nieprawda. Zaokrąglenie 0,5 w górę zaokrągla dokładnie połowę liczb - [0,.5)- w dół i dokładnie połowę liczb - [.5,1)- w górę. Zaokrąglanie do nawet nieznacznie odchyla liczby parzyste, ponieważ zaokrągla (.5,1.5)do 1, ale [1.5,2.5]do 2.
Jim Balter
11
@JimBalter Ponieważ zero nie jest zaokrąglane, zaokrąglanie do połowy w górę wprowadza dodatnie odchylenie, dlatego jest znane jako zaokrąglanie asymetryczne. „Zaokrąglij połowę do parzystości” nie działa, jeśli rozkład jest wystarczająco równy, a zaokrąglanie nie wpływa na liczby parzyste ani nieparzyste. Zobacz rozstrzyganie remisów zaokrągleń w połowie .
sdds
36

Możesz również użyć funkcji:

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

W zależności od architektury jest kilkukrotnie szybszy.

szymcio
źródło
To było dla mnie idealne, ponieważ Math.Round nie działał tak, jak chciałem.
Hanna
@cullub tak, tak. Konwertuje podwójne d, do którego dodano 0,5, na liczbę całkowitą.
Darrell,
To moja ulubiona metoda - działa w bardzo prosty sposób. O wiele krótszy i łatwiejszy do odczytania niż Math.Round (d, MidpointRounding.AwayFromZero) i bardziej zwięzły niż użycie instrukcji if do wyboru, czy zaokrąglić w dół, czy zaokrąglić w górę. AND, w rzeczywistości zwraca liczbę całkowitą na końcu, a nie podwójną
binderbound
3
Zobacz komentarz @ Eternal21 poniżej, aby zobaczyć dziwne zachowanie liczb ujemnych (MyRound (-1,2) = 0)
Chris,
2
Dla każdego, kto się zastanawia, problem wspomniany przez @Chris został prawdopodobnie rozwiązany poprzez sprawdzenie, czy wartość jest ujemna.
John Weisz
14
double d;
int rounded = (int)Math.Round(d);

źródło
5

Wiem, że to pytanie jest stare, ale natrafiłem na nie, szukając odpowiedzi na podobne pytanie. Pomyślałem, że podzielę się bardzo przydatną wskazówką, którą otrzymałem.

Podczas konwersji na int, po prostu dodaj .5do swojej wartości przed obniżeniem. Ponieważ intobniżenie do zawsze spada do niższej liczby (np. (int)1.7 == 1), Jeśli twój numer jest .5lub wyższy, dodanie .5podniesie go do następnej liczby, a obniżenie do intpowinno zwrócić poprawną wartość. (np. (int)(1.8 + .5) == 2)

Trent
źródło
13
Problem polega na tym, że próbujesz przekonwertować w ten sposób wartości ujemne. Na przykład -1,25 będzie równe 0. (-1,25 + 0,5 = 0,75, a po rzuceniu w dół to 0). Musisz więc odjąć 0,5 od wartości ujemnych.
Eternal
Można użyć+ 0.5 * Math.Abs(d)
Data
-1

W przypadku aparatu Unity użyj Mathf.RoundToInt .

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));
    }
}

Źródło

public static int RoundToInt(float f) { return (int)Math.Round(f); }
zwcloud
źródło
Q nie wspomina ani nie oznacza Unity.
XenoRo
@XenoRo Odpowiadałem na to stare pytanie dla tych, którzy szukają podobnych odpowiedzi podczas korzystania z Unity.
zwcloud
2
Możesz odpowiedzieć na własne pytania dotyczące dzielenia się wiedzą. Utwórz osobne pytanie specyficzne dla API (w tym przypadku Unity) w takich przypadkach. Odpowiedzi powinny być adekwatne do pytań. W przeciwnym razie może istnieć odpowiedź dla każdego interfejsu API języka C # z funkcją zaokrąglania.
XenoRo
-2

Opracowuję kalkulator naukowy z przyciskiem Int. Oto proste, niezawodne rozwiązanie:

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

Math.Round czasami daje nieoczekiwane lub niepożądane wyniki, a jawna konwersja na liczbę całkowitą (przez rzutowanie lub Convert.ToInt ...) często daje błędne wartości dla liczb o większej precyzji. Powyższa metoda wydaje się zawsze działać.

Mark Jones
źródło
2
Czy to nie zaokrągla w górę wszystkich liczb ujemnych i wszystkich dodatnich? Niekoniecznie jest to „najbliższa” liczba całkowita.
Tim Pohlmann,
to nie jest najbliższa liczba.
Samer Aamar
1
Biorąc pod uwagę 1,99, zwraca to 1,0.
Jon Schneider