Pourquoi diviser un float par un entier renvoie-t-il 0.0?
Donc, si j'ai une plage de nombres '0-1024' et que je veux les amener dans '0-255' , les mathématiques dicteraient de diviser l'entrée par le maximum que l'entrée sera (1024 dans ce cas) qui me donnera un nombre entre 0.0 - 1.0. puis multipliez cela par la plage de destination, (255).
, Qui est ce que je veux faire!
Mais pour une raison quelconque en Java (en utilisant le traitement), il retournera toujours une valeur de 0.
Le code serait aussi simple que celui-ci
float scale;
scale = (n/1024) * 255;
Mais je viens obtenez 0.0. J'ai essayé le double et int. ce fut en vain. Pourquoi!?
6 réponses
C'est parce que vous faites la division entière.
Divisez par un double ou un flotteur, et cela fonctionnera:
double scale = ( n / 1024.0 ) * 255 ;
Ou, si vous le voulez comme un flotteur,
float scale = ( n / 1024.0f ) * 255 ;
N / 1024 est division entière, ce qui donne un entier (ie. 0 dans ce cas).
Utilisez n / 1024.0
à la place.
Je présume n
est un int
. Parce que les constantes 1024 et 255 sont toutes les deux int
s, Tous les calculs de droite sont effectués avec l'arithmétique entière. Signifie que le résultat de n/1024
est tronqué à une valeur intégrale avant d'être multiplié par 255
.
L'une de ces modifications fera fonctionner les calculs correctement:
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.
Le dernier utilise toujours les mathématiques entières mais changer l'ordre des opérations signifie que vous n'obtiendrez pas la troncature indésirable à 0. Vous aurez toujours seulement obtenir des réponses entières, de sorte que vous perdrez des points décimaux dans les réponses.
Vous devez d'abord convertir automatiquement n en flottant au moyen d'une multiplication, sinon vous effectuez une opération entière, puis lancez le résultat, au lieu de faire l'opération entre les flottants.
float scale;
scale = n * 1.0 / 1024 * 255;
Dans votre cas n/1024
entraîne 0 comme vous faites la division entière. Pour surmonter cela, vous pouvez lancer n
à float
. Cela vous donnera un résultat compris entre 0.0
et 1.0
ensuite, vous multipliez par 255
et convertir le résultat en entier. Vous devez aussi déclarer scale
, comme int
int scale;
int n = 80;
scale = (int)(((float)n/1024) * 255);
D'autres ont déjà donné de bonnes réponses. Si vous voulez que votre échelle soit un entier (ce qui est logique si votre n est déjà un entier), vous pouvez faire
int scale = ((255 * n)/1024);
Notez que vous ne rencontrerez aucun problème avec ceci tant que ce sont les nombres, puisque n * 255 tiendra toujours dans un int lorsque le maximum n = 1024.
Plus souple serait
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();
}
Vous ne déborderez pas d'ints de cette façon, bien que j'admette que c'est un peu verbeux
Modifier:
Fondamentalement le même, mais moins maladroit (bien que pour des nombres très élevés, vous pourriez rencontrer des erreurs de précision)
int scale(int value, int old_max, int new_max){
double factor = (double) new_max / (double) old_max;
return factor * value;
}