2010-09-23 26 views
37

Donc, si j'ai une plage de nombres '0 - 1024' et que je veux les amener dans '0 - 255', les maths voudraient diviser l'entrée par le maximum que l'entrée sera (1024 dans ce cas) va me donner un nombre entre 0.0 - 1.0. puis multipliez cela par la plage de destination (255).Pourquoi la division d'un float par un entier renvoie 0.0?

C'est ce que je veux faire!

Mais pour une raison quelconque en Java (avec traitement) Il retourne toujours une valeur de 0.

Le code serait aussi simple que cela

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

Mais j'obtenir 0.0. J'ai essayé le double et int. Tout en rien. POURQUOI!?

+2

'n' doit également être défini comme' float'. –

+1

n n'a pas besoin d'être flottant, seulement numérique. cependant 1024 doit être flottant/double (1024.0) – KevinDTimm

Répondre

68

C'est parce que vous faites une division entière.

Diviser par un double ou un flotteur, et il fonctionnera:

double scale = (n/1024.0) * 255 ; 

Ou, si vous voulez comme un flotteur,

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

Merci beaucoup pour la réponse! :) –

19

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

Utilisez plutôt n/1024.0.

+0

+1 parce que c'est mieux que ma réponse :) – Agos

+0

Merci beaucoup pour la réponse! :) –

+0

Merci! Ça marche. n/1024.0f –

2

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

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

Je présume que n est un int. Comme 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. Ce qui signifie que le résultat de n/1024 est tronqué à une valeur intégrale avant d'être multiplié par 255.

Chacune de ces modifications feront les calculs fonctionnent 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 les mathématiques entier encore, mais l'ordre de commutation des opérations signifie que vous ne serez pas la troncature indésirable à 0. Vous aurez toujours obtenir seulement des réponses entières, de sorte que vous perdrez tous les points décimaux dans les réponses.

+0

Merci beaucoup pour la réponse! :) –

2

Dans votre cas, n/1024 donne 0 comme division entière. Pour surmonter cela, vous pouvez lancer n à float. Cela vous donnera un résultat entre 0.0 et 1.0 ensuite vous multipliez avec 255 et renvoyez le résultat à l'entier. Aussi, vous devez déclarer scale comme int

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

autres ont donné de grandes réponses déjà.Si vous voulez que votre échelle pour être un entier (ce qui est logique si votre n est un entier déjà), vous pouvez faire

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

Notez que vous ne frapperez aucun problème avec ce aussi longtemps que ce sont les numéros, puisque n * 255 sera toujours adapté 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ébordera pas tout ints cette façon, même si je l'admets est bit verbeux

Edit:

Basicly même, mais moins maladroits (bien que pour un nombre très élevé que vous pourriez rencontrer des erreurs de Precission)

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

Hé, c'est pourquoi je déteste BigInteger et BigDecimal. –