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


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

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.


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.


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

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)


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

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ć.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.