Почему деление поплавка на целое число возвращает 0.0?

поэтому, если у меня есть диапазон чисел "0 - 1024", и я хочу привести их в "0 - 255", математика будет диктовать разделить вход на максимум, который будет (1024 в этом случае), который даст мне число между 0.0 - 1.0. затем умножьте это на диапазон назначения, (255).

что я и хочу сделать!

но по какой-то причине в Java (с использованием обработки) он всегда будет возвращать значение 0.

код будет таким же простым, как это

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

но я просто 0.0. Я пробовал double и int. все безрезультатно. Почему??

6 ответов


Это потому, что вы делаете целочисленное деление.

разделите на double или float, и он будет работать:

double scale = ( n / 1024.0 ) * 255 ;

или, если вы хотите его, как поплавок,

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

n / 1024 is целочисленное деление, который дает целое число (т. е.. 0 в данном случае).

использовать .


предполагаю n это int. Потому что константы 1024 и 255 оба ints все вычисления правой стороны выполняются с помощью целочисленной арифметики. Значение результата n/1024 усекается до интегрального значения перед умножением на 255.

любая из этих модификаций сделает расчеты работать правильно:

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.

последний использует целочисленную математику, но изменения порядка операций означает, что вы не получите нежелательные усечение до 0. Вы все равно получите только целочисленные ответы, поэтому вы потеряете любые десятичные точки в ответах.


сначала вы должны автоматически бросить n, чтобы плавать с помощью умножения, иначе вы выполняете целочисленную операцию, а затем бросаете результат, а не выполняете операцию между поплавками.

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

в вашем случае n/1024 приводит к 0, как вы делаете целочисленное деление. Чтобы преодолеть это, вы можете бросить n to float. Это даст вам результат между 0.0 и 1.0 далее вы умножаете с 255 и верните результат в integer. Также вам нужно объявить scale as int

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

другие уже дали отличные ответы. Если вы хотите, чтобы ваш масштаб был целым числом (что имеет смысл, если ваш n уже является целым числом), вы можете сделать

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

обратите внимание, что вы не нажмете никаких проблем с этим, пока это числа, так как n * 255 всегда будет вписываться в int, когда максимум n = 1024.

более гибким будет

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

вы не будете переполнять какие-либо ints таким образом, хотя я признаю, что это немного многословный

Edit:

В основном то же самое, но менее неуклюжий (хотя для очень больших чисел вы можете столкнуться с некоторыми ошибками точности)

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