2010-09-23 12 views
37

Quindi se ho un intervallo di numeri '0 - 1024' e voglio portarli in '0 - 255', la matematica dovrebbe dettare per dividere l'input dal massimo che l'input sarà (1024 in questo caso) che mi darà un numero compreso tra 0.0 - 1.0. quindi moltiplicare quello per l'intervallo di destinazione, (255).Perché la divisione di un float per un intero restituisce 0.0?

Quale è quello che voglio fare!

Ma per qualche motivo in Java (usando Processing) Sarà sempre restituire un valore pari a 0.

il codice sarebbe semplice come questo

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

Ma ho solo ottenere 0.0. Ho provato doppio e int. tutto inutilmente. PERCHÉ!?

+2

'n' deve anche essere definito come' float'. –

+1

n non deve essere mobile, solo numerico. tuttavia 1024 deve essere float/double (1024.0) – KevinDTimm

risposta

68

È perché si sta facendo divisione integer.

Divide da un doppio o di un galleggiante, e funzionerà:

double scale = (n/1024.0) * 255 ; 

Oppure, se si vuole come un galleggiante,

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

Grazie mille per la risposta! :) –

19

n/1024 è divisione intera, che produce un numero intero (cioè 0 in questo caso).

Utilizzare invece n/1024.0.

+0

+1 perché è meglio della mia risposta :) – Agos

+0

Grazie mille per la risposta! :) –

+0

Grazie! Funziona. n/1024.0f –

2

È necessario eseguire il cast automatico di n per eseguire il float mediante una moltiplicazione FIRST, altrimenti si esegue un'operazione di numero intero e quindi si esegue il cast del risultato, invece di eseguire l'operazione tra i float.

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

presumo n è un int. Poiché le costanti 1024 e 255 sono entrambe int s tutti i calcoli sul lato destro vengono eseguiti con l'aritmetica dei numeri interi. Significato del risultato di n/1024 viene troncato a un valore integrale prima di essere moltiplicato per 255.

Qualsiasi di queste modifiche renderanno i calcoli funzionano correttamente:

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. 

L'ultimo utilizza matematica intero ancora ma il passaggio l'ordine delle operazioni significa che non sarà possibile ottenere il troncamento indesiderato a 0. Avrete ottieni comunque solo risposte intere, quindi perderai i punti decimali nelle risposte.

+0

Grazie mille per la risposta! :) –

2

Nel tuo caso n/1024 restituisce 0 come si sta facendo divisione integer. Per superare questo problema, puoi trasmettere n a float. Questo ti darà un risultato tra 0.0 e 1.0 poi moltiplica con 255 e restituisci il risultato all'intero. Inoltre è necessario dichiarare scale come int

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

altri hanno dato già grandi risposte.Nel caso in cui si desidera che la scala di essere un numero intero (che ha senso se il n è un numero intero già), si potrebbe fare

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

Nota che non ha colpito alcun problema con questo fintanto che questi sono i numeri, dal n * 255 saranno sempre in forma in un int quando il massimo n = 1024.

più flessibile sarebbe

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

non sarà traboccare alcun interi in questo modo, anche se devo ammettere che questo è un bit verbose

Edit:

Fondamentalmente lo stesso, ma meno goffo (anche se per i numeri molto alti si potrebbe incorrere in alcuni errori precission)

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

Heh, questo è il motivo per cui odio BigInteger e BigDecimal. –

Problemi correlati