2012-08-23 22 views
8

Nie można wymyślić lepszego tytułu. Problem jest następujący: Mam "int i", może to być dowolna wartość. moim celem jest przekształcenie "int i" w najbliższą liczbę podzielną przez . Na przykład, mam i = 33. Wtedy zostanie zmieniony na (16x2). Ale jeśli dostanę i = 50, to zostanie zmieniony na (16x3).Java - Jak sprawdzić, czy podział jest liczbą całkowitą czy zmiennoprzecinkową?

Próbowałem wielu rzeczy, na przykład:

for (int x = i; x < 999; x++){ 
if ((i - x)/16 *is an integer*){ 
i = i - x; 
} 

ale nie wiem jak sprawdzić czy jego liczbę całkowitą. Więc może mój poprzedni kod działa, ale po prostu muszę znaleźć sposób na sprawdzenie, czy jest liczbą całkowitą czy zmiennoprzecinkową. Więc ... każda pomoc jest doceniana.

+4

Podział dwóch int będzie zawsze miał wynik końcowy. Zamiast tego możesz użyć modulus ('%'). – GriffeyDog

+0

FWIW, Proponuję wypróbować inne podejście, aby rozwiązać ten problem. To podejście do szukania liczby, którą można odjąć od i, aby uzyskać wielokrotność liczby 16, jest niezwykle nieefektywne. A co, jeśli najbliższa wielokrotność liczby 16 jest większa niż I? – Alex

Odpowiedz

5

Ponieważ wszystkie wskazówki, które jest podzielna przez 16 lat będzie miał ich ostatnie 4 bity ustawione na 0. można osiągnąć to, co chcesz, bez pętli lub nawet jeśli stwierdzenie:

i &= 0xfffffff0; // Sets i to the greatest multiple of 16 less than i, or 0 for i < 16 

na przykład:

int i = 50; 
i &= 0xfffffff0; // i == 48 

i = 39; 
i &= 0xfffffff0; // i == 32 

i = 16; 
i &= 0xfffffff0; // i == 16 
+0

Działa idealnie! – user1541106

4

(i - x)/16 jest całkowita, gdy pozostała część (i - x)/16 0. Zastosowanie% (moduł) operatora, takie jak:

if((i - x)%16 == 0) { 
    // (i-x)/16 is integer 
} 
12

użytkowania operatora Mod. Mod daje resztę operacji podziału.

public boolean isEvenlyDivisable(int a, int b) { 
    return a % b == 0; 
} 
1

Aby dowiedzieć się, czy dana liczba równo dzieli innego, sprawdzić inne odpowiedzi, Modulo (%) jest sposobem, aby to zrobić.

Aby zrobić to, co chcesz zrobić powyżej, nie trzeba pętlę:

public int nearestDivider(final int input) 
{ 
    final int multiple = input/16; // this will divide by 16 and it's integer math, so it loses the decimal 
    return multiple * 16; 
} 

Że wróci 48, jeśli dasz mu 50 jak swoim przykładzie.

Jeśli naprawdę chcesz najbliższym następnie trzeba będzie zrobić kilka zmiennoprzecinkowej Division

public int nearestDivider(final int input) 
{ 
    final int multiple = Math.round((float) input/16); 
    return multiple * 16; 
} 

Teraz powraca 46 48, 149 144 powraca itp

+0

W zależności od definicji terminu "najbliższy", może być konieczne dodanie 16. – Alex

+0

Prawda, jego przykłady (i kod) zdawały się wskazywać, chciał, aby najbliższy był mniejszy lub równy ... – xbakesx

+0

Tak, to trochę trudne do wywnioskowania zamiar z próbki o rozmiarze 2 ... – Alex

4

Istnieje szereg zagadnień z uderzające Twój oryginalny kod:

  1. Jeśli zaokrąglisz w dół do najbliższej wielokrotności 16, oznacza to, że najwyższa wartość, jaką możesz mieć do substr akt 15. To dlatego, że górna granica twojej pętli powinna wynosić co najwyżej 15.
  2. Jak zauważyli inni, możesz użyć operatora modulo (%), aby określić dokładną wartość odjąć od danej wartości, aby zaokrąglić ją do najbliższa wielokrotność 16. To całkowicie usuwa potrzebę pętli.
  3. Ale ponieważ 16 jest potęgą 2, a ponieważ liczby całkowite są reprezentowane jako liczba binarna z 32 cyframi (tj. 32 bitów), można obliczyć wartość bardziej bezpośrednio za pomocą maski bitowej wyzerować dowolne cyfry mniejsze niż 16 w numer. W Javie można użyć binarnego operatora & w tym celu, jak poniżej: i & 0xfffffff0. Spowoduje to wyzerowanie 4 ostatnich cyfr (reprezentujących: 8-4-2-1), co skutecznie zaokrągli liczbę do najbliższej wartości podzielnej przez 16.
  4. Jeśli chcesz wykonać podział liczb całkowitych i zignorować resztę, możesz po prostu przesunąć (>>) o 4 bity, aby to zrobić.
0

Jeśli potrzebujesz najbliższy wielokrotność 16, to masz dwa przypadki do czynienia z nieparzystej wielokrotności 8. 1. 8 staje się 16, 24 staje się 32 2. 8 staje się 0, 24 staje się 16

na pierwszy:

int j = ((i+8)/16)*16; 

W drugim przypadku:

int j = ((i+7)/16)*16; 

Jeśli chcesz zawsze zaokrąglić DOWN (tj. 17 staje się 16 i 15 staje 0):

int j = (i/16)*16; 

Jeśli chciałeś zawsze zaokrąglić w górę (nie co Twój przykład mówi), byś zrobił to zamiast:

int j = ((i+15)/16)*16; 
0

W celu sprawdzenia, czy losowe wyniki Division w liczbę całkowitą lub ułamek potrzebne są następujące elementy:

int n = 9; 
int p = 3; 

if (n % p == 0) { 
    //the division results in an integer. 
} 
else 
{ 
    //the division results in a fraction. 
} 

Można to zrobić jako alternatywę:

if (n/p == Math.ceil((double) n/(double) p)) { 
    //the division results in an integer. 
} 
else 
{ 
    //the division results in a fraction. 
} 

trzeba Math .ceil(), a nie okrągły lub podłogowy, ponieważ podział całkowity jest prawie równy podłodze, a ułamek zostanie zaokrąglony w dół i pojawi się jako "dzielenie całkowite".

Powiązane problemy