Perché la divisione di un float per un intero restituisce 0.0?

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 darà me un numero compreso tra 0.0 – 1.0. quindi moltiplicare quello per l’intervallo di destinazione, (255).

Che è quello che voglio fare!

Ma per qualche ragione in Java (usando Processing) restituirà sempre un valore di 0.

Il codice sarebbe semplice come questo

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

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

È perché stai facendo la divisione integer.

Dividi per un doppio o un float, e funzionerà:

 double scale = ( n / 1024.0 ) * 255 ; 

Oppure, se lo vuoi come galleggiante,

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

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

Utilizzare invece n / 1024.0 .

Presumo che n sia un int . Poiché le costanti 1024 e 255 sono entrambe int e tutti i calcoli sul lato destro vengono eseguiti con l’aritmetica dei numeri interi. Significa che il risultato di n/1024 viene troncato su un valore integrale prima di essere moltiplicato per 255 .

Qualsiasi di queste modifiche renderà i calcoli funzionanti 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 ancora la matematica intera ma cambiando l’ordine delle operazioni significa che non si otterrà il troncamento indesiderato a 0. Tuttavia, si otterranno comunque solo risposte intere, quindi si perderanno i punti decimali nelle risposte.

Dovresti eseguire il cast automatico di n per renderlo mobile per mezzo di una moltiplicazione FIRST, altrimenti esegui un’operazione intera e quindi esegui il cast del risultato, invece di eseguire l’operazione tra i float.

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

Nel tuo caso n/1024 risulta in 0 mentre stai facendo divisione in interi. Per superare questo puoi lanciare n per 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 la scale come int

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

altri hanno già dato grandi risposte. Se vuoi che la tua scala sia un numero intero (che ha senso se il tuo n è già un intero), potresti fare

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

Si noti che non si verificheranno problemi con questo fintanto che questi sono i numeri, dal momento che n * 255 si adatta sempre ad 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 esagererai mai in questo modo, anche se ammetto che questo è un po ‘prolisso

Modificare:

Fondamentalmente lo stesso, ma meno goffo (anche se per numeri molto alti potresti incorrere in errori di precissione)

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