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

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

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

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

Код будет так просто, как этот

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

Но я просто получаю 0.0. Я пробовал двойной и инт. все безрезультатно. ЗАЧЕМ!?

6 ответов

Решение

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

Разделите на двойной или поплавок, и это сработает:

double scale = ( n / 1024.0 ) * 255 ;

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

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

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

использование n / 1024.0 вместо.

Я предполагаю 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. Вы все равно будете получать только целочисленные ответы, поэтому вы потеряете все десятичные точки в ответах.

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

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

В твоем случае n/1024 приводит к 0, поскольку вы делаете целочисленное деление. Чтобы преодолеть это вы можете разыграть n в float, Это даст вам результат между 0.0 а также 1.0 затем вы умножаете с 255 и приведите результат обратно к целому числу. Также вам нужно заявить scale как 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();
}

Таким образом, вы не переполните целые числа, хотя я признаю, что это немного многословно

Редактировать:

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

int scale(int value, int old_max, int new_max){
  double factor = (double) new_max / (double) old_max;
  return factor * value;
}
Другие вопросы по тегам