2010-09-23 20 views
37

Więc jeśli mam zakres liczb "0 - 1024" i chcę je wprowadzić w "0 - 255", matematyka dyktuje, aby podzielić wejście przez maksimum będzie wejście (1024 w tym przypadku), które da mi liczbę pomiędzy 0,0 - 1,0. następnie pomnóż to przez docelowy zakres, (255).Dlaczego dzielenie liczby zmiennoprzecinkowej przez liczbę całkowitą zwraca wartość 0,0?

Co chcę robić!

Ale z jakiegoś powodu w Java (przy użyciu Processing) to zawsze zwraca wartość 0.

kodu byłoby tak proste, jak to

float scale; 
scale = (n/1024) * 255; 

Ale ja po prostu 0.0. Próbowałem podwójne i int. wszystko bez skutku. CZEMU!?

+2

'n' musi być zdefiniowany jako' float'. –

+1

n nie musi być zmiennoprzecinkowy, tylko numeryczny. jednakże 1024 musi być unoszony/podwójny (1024.0) – KevinDTimm

Odpowiedz

68

To dlatego, że robisz podział na liczby całkowite.

Dzielenie przez podwójne lub pacą, a to będzie działać:

double scale = (n/1024.0) * 255 ; 

Albo, jeśli chcesz go jako float

float scale = (n/1024.0f) * 255 ; 
+1

Dziękuję bardzo za odpowiedź! :) –

19

n/1024 jest całkowitą podział, który daje liczbę całkowitą (tj. 0 w tym przypadku).

Zamiast tego należy użyć n/1024.0.

+0

+1, ponieważ jest lepsza niż moja odpowiedź :) – Agos

+0

Dziękuję bardzo za odpowiedź! :) –

+0

Dzięki! To działa. n/1024.0f –

2

Powinieneś automatycznie rzucić n, aby przemieścić się za pomocą mnożenia PIERWSZY, w przeciwnym razie wykonujesz operację całkowitą, a następnie rzutujesz wynik, zamiast wykonywać operację między spławikami.

float scale; 
scale = n * 1.0/1024 * 255; 
7

Przypuszczam n jest int. Ponieważ stałe 1024 i 255 są zarówno obliczeniami po prawej stronie są wykonywane z arytmetyczną liczbą całkowitą. Oznacza to, że wynik n/1024 jest obcinany do wartości integralnej przed pomnożeniem przez 255.

Każda z tych zmian uczyni obliczenia działa poprawnie:

scale = n/1024.0 * 255.0;  // Use double constants. 
scale = (double) n/1024 * 255; // Convert n to a double. 
scale = n * 255/1024;   // Multiply before dividing. 

Ten ostatni wykorzystuje całkowitą matematyki nadal jednak włączeniem kolejność operacji oznacza, że ​​nie dostanie niepożądane obcinanie 0. będziesz wciąż otrzymuję tylko liczby całkowite, więc stracisz w odpowiedziach liczbę dziesiętną.

+0

Dziękuję bardzo za odpowiedź! :) –

2

W twoim przypadku n/1024 daje 0, ponieważ robisz podział całkowity. Aby temu zaradzić, możesz rzucić n do float. To da ci wynik pomiędzy 0.0 i 1.0 następnie pomnożyć przez 255 i rzutuje wynik z powrotem na liczbę całkowitą. Również trzeba zadeklarować scale jak int

int scale; 
int n = 80; 
scale = (int)(((float)n/1024) * 255); 
2

inni dali już wielkie odpowiedzi.W przypadku, gdy chcesz, aby twoja waga będzie liczbą całkowitą (co ma sens, jeśli n jest już liczbą całkowitą), można zrobić

int scale = ((255 * n)/1024); 

pamiętać, że nie będzie żadnych problemów hit z tym tak długo, jak są to numery, ponieważ n * 255 zawsze będzie pasować int gdy maksymalna n = 1024.

bardziej elastyczny byłoby

int scale(int value, int old_max, int new_max){ 
    java.math.BigInteger big_value = java.math.BigInteger.valueOf(value); 
    java.math.BigInteger big_old_max = java.math.BigInteger.valueOf(old_max); 
    java.math.BigInteger big_new_max = java.math.BigInteger.valueOf(new_max); 
    java.math.BigInteger mult = big_value.multiply(big_old_max); 
    return (int) mult.devide(big_new_max).doubleValue(); 
} 

nie będzie przelewać żadnych ints ten sposób, choć muszę przyznać, że jest to bit verbose

Edit:

Basicly samo, ale mniej niezgrabne (choć na bardzo dużych ilościach może napotkać pewne błędy precission)

int scale(int value, int old_max, int new_max){ 
    double factor = (double) new_max/(double) old_max; 
    return factor * value; 
} 
+0

Heh, właśnie dlatego nienawidzę BigInteger i BigDecimal. –

Powiązane problemy