web-dev-qa-db-fra.com

Pourquoi la division d'un flottant par un entier renvoie-t-elle 0,0?

Donc, si j'ai une plage de nombres '0 - 1024' et que je veux les mettre en '0 - 255', les maths dicteraient de diviser l'entrée par le maximum que l'entrée sera (1024 dans ce cas), ce qui donnera moi un nombre compris entre 0,0 et 1,0. multipliez ensuite par la plage de destination, (255).

C'est ce que je veux faire!

Mais pour une raison quelconque dans Java (en utilisant le traitement), il retournera toujours une valeur de 0.

Le code serait aussi simple que cela

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

Mais je reçois juste 0,0. J'ai essayé le double et l'int. Tout en rien. POURQUOI!?

40
Arif Driessen

C'est parce que vous faites une 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 flotteur,

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

n/1024 est division entière, ce qui donne un entier (c'est-à-dire 0 dans ce cas).

Utilisation n / 1024.0 au lieu.

19
Alexandre C.

Je suppose que n est un int. Comme les constantes 1024 et 255 sont toutes les deux ints, tous les calculs à droite sont effectués avec une arithmétique entière. Signification du résultat de n/1024 est tronqué à une valeur intégrale avant d'être multiplié par 255.

Chacune 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 des mathématiques entières, mais en changeant l'ordre des opérations, vous n'obtiendrez pas la troncature indésirable à 0. Cependant, vous n'obtiendrez que des réponses entières, vous perdrez donc toute décimale dans les réponses.

7
John Kugelman

Vous devez lancer automatiquement n pour flotter au moyen d'une multiplication en PREMIER, sinon vous effectuez une opération entière, puis vous convertissez le résultat, au lieu de faire l'opération entre les flottants.

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

Dans ton cas n/1024 donne 0 lorsque vous effectuez une division entière. Pour surmonter cela, vous pouvez convertir n en float. Cela vous donnera un résultat entre 0.0 et 1.0 ensuite vous multipliez avec 255 et convertissez le résultat en entier. Vous devez également déclarer scale comme int

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

d'autres ont déjà donné d'excellentes 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 le faire

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

Notez que vous ne rencontrerez aucun problème avec cela tant qu'il s'agit des nombres, car n * 255 tiendra toujours dans un entier lorsque le maximum n = 1024.

plus flexible 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 de cette façon, bien que j'avoue que c'est un peu bavard

Éditer:

Fondamentalement les mêmes, mais moins maladroits (bien que pour des nombres très élevés, vous puissiez 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;
}
2
Martijn