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

Итак, если у меня есть диапазон чисел «0–1024», и я хочу привести их к «0–255», математика диктует разделить ввод на максимальное значение ввода (в данном случае 1024), что даст мне число от 0,0 до 1,0. затем умножьте это на диапазон назначения (255).

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

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

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

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

Но у меня просто 0.0. Я пробовал double и int. все безрезультатно. ЗАЧЕМ!?


person Arif Driessen    schedule 23.09.2010    source источник
comment
n также должен быть определен как float.   -  person Felix Kling    schedule 23.09.2010
comment
n не обязательно должен быть с плавающей запятой, только числовой. однако 1024 должно быть числом с плавающей запятой/двойным числом (1024.0)   -  person KevinDTimm    schedule 23.09.2010


Ответы (6)


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

Разделите на двойное число или число с плавающей запятой, и это сработает:

double scale = ( n / 1024.0 ) * 255 ;

Или, если вы хотите, чтобы он был поплавком,

float scale = ( n / 1024.0f ) * 255 ;
person tim_yates    schedule 23.09.2010
comment
Большое спасибо за ответ! :) - person Arif Driessen; 23.09.2010

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

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

person Alexandre C.    schedule 23.09.2010
comment
Большое спасибо за ответ! :) - person Arif Driessen; 23.09.2010

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

person John Kugelman    schedule 23.09.2010
comment
Большое спасибо за ответ! :) - person Arif Driessen; 23.09.2010

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

float scale;
scale = n * 1.0 / 1024 * 255;
person Agos    schedule 23.09.2010

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

int scale;
int n = 80; 
scale = (int)(((float)n/1024) * 255);
person codaddict    schedule 23.09.2010

другие уже дали отличные ответы. Если вы хотите, чтобы ваша шкала была целым числом (что имеет смысл, если ваше 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;
}
person Martijn    schedule 23.09.2010
comment
Хех, вот почему я ненавижу BigInteger и BigDecimal. - person Tony Ennis; 23.09.2010