¿Por qué dividir un flotador por un entero devuelve 0.0?


Así que si tengo un rango de números '0 - 1024' y quiero llevarlos a '0 - 255', las matemáticas dictarían dividir la entrada por el máximo que será la entrada (1024 en este caso) lo que me dará un número entre 0.0 - 1.0. luego multiplique eso por el rango de destino, (255).

Que es lo Que quiero hacer!

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

El código sería tan simple como este

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

Pero yo solo obtener 0.0. He intentado doble e int. todo en vano. ¡POR QUÉ!?

Author: ataulm, 2010-09-23

6 answers

Es porque estás haciendo división entera.

Divida 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 ;
 69
Author: tim_yates,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-21 08:37:04

N / 1024 es división entera, que produce un entero (ie. 0 en este caso).

Use n / 1024.0 en su lugar.

 19
Author: Alexandre C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-23 14:51:49

Supongo que n es un int. Debido a que las constantes 1024 y 255 son ambas int s, todos los cálculos del lado derecho se realizan con aritmética de enteros. Lo que significa que el resultado de n/1024 está siendo truncado a un valor integral antes de ser multiplicado por 255.

Cualquiera de estas modificaciones hará que los cálculos funcionen 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 utiliza números enteros todavía, pero cambiar el orden de las operaciones significa que no obtendrá el truncamiento no deseado a 0. Vas a sin embargo, solo obtendrás respuestas enteras, por lo que perderás cualquier punto decimal en las respuestas.

 7
Author: John Kugelman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-23 14:52:43

Usted debe auto-cast n para flotar por medio de una multiplicación PRIMERO, de lo contrario usted está haciendo una operación entera y luego fundir el resultado, en lugar de hacer la operación entre flotadores.

float scale;
scale = n * 1.0 / 1024 * 255;
 2
Author: Agos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-23 14:52:01

En su caso n/1024 resulta en 0 mientras está haciendo la división de enteros. Para superar esto puedes lanzar n a float. Esto le dará un resultado entre 0.0 y 1.0 luego se multiplica con 255 y se vuelve a convertir el resultado en entero. También debe declarar scale como int

int scale;
int n = 80; 
scale = (int)(((float)n/1024) * 255);
 2
Author: codaddict,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-23 14:53:33

Otros ya han dado grandes respuestas. En caso de que desee que su escala sea un entero (lo que tiene sentido si su n ya es un entero), podría hacer

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

Tenga en cuenta que no encontrará ningún problema con esto siempre y cuando estos sean los números, ya que n * 255 siempre cabrá en un int cuando el máximo n = 1024.

Más flexible sería

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

No desbordarás ningún ints de esta manera, aunque admito que esto es un poco detallado

Editar:

Básicamente lo mismo, pero menos torpe (aunque para números muy altos puede 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;
}
 2
Author: Martijn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-25 07:54:18