Подтвердить что ты не робот

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

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

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

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

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

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

Но я просто получаю 0.0. Я попробовал double и int. все безрезультатно. ПОЧЕМУ!?

4b9b3361

Ответ 1

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

Разделите двойным или поплавком, и он будет работать:

double scale = ( n / 1024.0 ) * 255 ;

Или, если вы хотите, чтобы это было как float,

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

Ответ 2

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

Используйте n / 1024.0 вместо этого.

Ответ 3

Я предполагаю, что n является int. Поскольку константы 1024 и 255 оба int, все вычисления правой стороны выполняются с целочисленной арифметикой. Значение результата 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. Вы все равно получите только целые ответы, так что вы потеряете десятичные точки в ответах.

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

другие уже дали большие ответы. Если вы хотите, чтобы ваш масштаб был целым (что имеет смысл, если ваш 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;
}