2010-09-23 23 views
37

Así que si tengo un rango de números '0 - 1024' y quiero ponerlos en '0 - 255', las matemáticas dictarían dividir la entrada por el máximo de la entrada (1024 en este caso) que me dará un número entre 0.0 - 1.0. luego multiplique eso por el rango de destino, (255).¿Por qué dividir un flotante por un entero devuelve 0.0?

¡Qué es lo que quiero hacer!

Pero por alguna razón en Java (usando Processing) Es siempre devolverá un valor de 0.

el código sería tan simple como esto

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

Pero acabo de obtener 0.0. He intentado doble e int. todo fue en vano. ¿¡POR QUÉ!?

+2

'n' también debe ser definido como 'float'. –

+1

n no necesita ser flotante, solo numérico. sin embargo, 1024 debe ser flotante/doble (1024.0) – KevinDTimm

Respuesta

68

Es porque estás haciendo una división entera.

Dividir por un doble o un flotador, y funcionará:

double scale = (n/1024.0) * 255 ; 

O, si lo quieres como un flotador,

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

¡Muchas gracias por la respuesta! :) –

19

n/1024 es división entera, que produce un número entero (es decir, 0 en este caso).

Use n/1024.0 en su lugar.

+0

+1 porque es mejor que mi respuesta :) – Agos

+0

¡Muchas gracias por la respuesta! :) –

+0

¡Gracias! Funciona. n/1024.0f –

2

Debe autoevaluar n para flotar mediante una multiplicación PRIMERO, de lo contrario, se está haciendo una operación entera y luego se arroja el resultado, en lugar de hacer la operación entre flotantes.

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

supongo n es un int. Como las constantes 1024 y 255 son ambas int s, todos los cálculos del lado derecho se realizan con aritmética entera. Lo que significa que el resultado de n/1024 se trunca a un valor integral antes de multiplicarse por 255.

Cualquiera de estas modificaciones se hacen los cálculos funcionan correctamente:

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. 

El último que usa las matemáticas número entero todavía, pero cambiando el orden de las operaciones significa que no obtendrá el truncamiento no deseada a 0. Usted aún así, solo obtendrá respuestas enteras, por lo que perderá puntos decimales en las respuestas.

+0

¡Muchas gracias por la respuesta! :) –

2

En su caso, n/1024 da como resultado 0 ya que está haciendo división de enteros. Para superar esto, puede convertir n en float. Esto le dará un resultado entre 0.0 y 1.0 a continuación, multiplique con 255 y vuelva a convertir el resultado en entero. También tiene que declarar como scaleint

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

otros han dado grandes respuestas ya.En caso de que usted quiere que su escala sea un entero (lo cual tiene sentido si su n es un número entero ya), se puede hacer

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

Observe que no se llegará a ningún problema con esto siempre y cuando estos son los los números, ya que n * 255 serán siempre encajan en un int cuando el máximo n = 1024.

más flexibles serían

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

Usted no va a desbordar cualquier enteros de esta manera, aunque admito que esto es una bit verbose

Editar:

Básicamente lo mismo, pero menos torpe (aunque por números muy altos usted podría encontrarse con algunos errores de Precisión)

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

Heh, es por eso que odio BigInteger y BigDecimal. –

Cuestiones relacionadas